java的容器基础入门

1.数组与其他容器的区别

效率较容器高(访问数据的效率是最高的),大小在生命周期类不能改变,可以存储基本类似的数据,而其他容器在运行时都是作为Object处理(编译时会进行检验,编译时泛型会去除作为Object处理,容器存储基本类型的原因是自动装拆箱,所以效率会降低。

2.List

ArriyList  基于数组,查询与更改效率高,增删效率低 ,可重复。

自定义ArriyList 集合

public class MyArraylist {
    private Object arrList[];
    private int size;

    public MyArraylist() {
        this(10);
    }

    public MyArraylist(int bound) {
        if (bound < 0) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        arrList = new Object[bound];
    }

    public void add(Object obj) {
        if (size >= arrList.length) {
            Object arrList1[] = new Object[2 * size + 1];
            System.arraycopy(arrList, 0, arrList1, 0, size);
            arrList = arrList1;
        } else {
            arrList[size++] = obj;
        }
    }

    public int size() {
        return size;
    }

    public Object get(int index) {
        boundCheck(index);
        return arrList[index];
    }

    public void remove(int index) {
        boundCheck(index);
        System.arraycopy(arrList, index + 1, arrList, index, size);
        arrList[size--] = null;
    }

    public boolean remove(Object obj) {
        for (int i = 0; i < size; i++) {
            if (arrList[i].equals(obj)) {
                remove(i);
                return true;
            }
        }
        return false;
    }

    public Object set(int index, Object obj) {
        boundCheck(index);
        return arrList[index] = obj;
    }

    public void boundCheck(int index) {
        if (index < 0 || index >= size) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void add(int index, Object obj) {
        if (index == size) {
            add(obj);
        } else {
            boundCheck(index);
            arrList[index] = obj;
            Object transfer = arrList[size - 1];
            System.arraycopy(arrList, index, arrList, index + 1, size);
            add(transfer);
            size++;
        }
    }

    public static void main(String[] args) {
        MyArraylist ml = new MyArraylist();
        ml.add("aaa");
        ml.add("bbb");
        ml.add("ccc");
        ml.set(1, "ddd");
        System.out.println(ml.size());
        System.out.println(ml.get(0));

    }
}

vector 向量 ,线程安全 ,基于数组 ,可重复

LinkedList  基于链表,查询与更改效率低,增删效率高 ,可重复。

自定义LinkedList 集合

class Node {
    //不被垃圾回收器回收的原因是因为垃圾回收的算法是基于根搜索算法
    private Node previse;
    private Object obj;
    private Node next;

    public Node() {
        super();
    }

    public Node(Node previse, Object obj, Node next) {
        super();
        this.previse = previse;
        this.obj = obj;
        this.next = next;
    }

    public Node getPrevise() {
        return previse;
    }

    public void setPrevise(Node previse) {
        this.previse = previse;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

}
public class MyLinkelist {
    private Node first;
    private Node last;
    private int size;

    public void add(Object obj) {
        if (first == null) {
            Node n = new Node();
            n.setPrevise(null);
            n.setObj(obj);
            n.setNext(null);
            first = n;
            last = n;
        } else {
            Node n = new Node();
            n.setPrevise(last);
            n.setObj(obj);
            n.setNext(null);
            last.setNext(n);
            last = n;
        }
        size++;
    }

    public int size() {
        return size;
    }

    public Object get(int index) {
        rangeCheck(index);
        Node temp = first;
        for (int i = 0; i < index; i++) {
            temp = temp.getNext();
        }
        return temp.getObj();
    }

    public void remove(int index) {
        rangeCheck(index);
        Node temp = first;
        for (int i = 0; i < index; i++) {
            temp = temp.getNext();
        }
        Node pre = temp.getPrevise();
        Node nt = temp.getNext();
        nt.setPrevise(pre);
        pre.setNext(nt);
        size--;

    }

    public void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            try {
                throw new Exception();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        MyLinkelist ml = new MyLinkelist();
        ml.add("aaa");
        ml.add("bbb");
        ml.add("ccc");
        ml.remove(1);
        System.out.println(ml.size());
        System.out.println(ml.get(0));
        
    }
}

3.Set

HashSet   不可重复,效率高,重写了hashCode方法,通过哈希值计算下标位置,下标相同放置在同一个区间采用链表结构,基于HashMap

自定义HashSet 集合(略)

TreeSet  实现Comparalbe接口重写compareTo,不可重复,放入后改变值不会影响顺序,放入元素时排序的,利用的是比较器的值是否为0来去重,大于小于0来排序

LinkedHashSet  不可重复

自定义

4.Map

HashMap 键不可重复,效率高,重写了hashCode方法,,通过哈希值计算下标位置,下标相同放置在同一个区间采用链表结构,基于数组加链表,键可以一个为null,值可以多个为null

自定义HashMap(只是简单的实现,没有重写hashcode和equals方法,没有考虑各个区间的均衡分布)

public class MyHashMap<K, V> {
    LinkedList<Node<K, V>>[] objs;
    int n;

    public MyHashMap() {
        this.n = 10;
        this.objs = new LinkedList[n];
    }

    public void put(K k, V v) {
        int mod = k.hashCode() % n;
        if (objs[mod] == null) {
            objs[mod] = new LinkedList<>();
        }
        int flag = 1;
        for (int i = 0; i < objs[mod].size(); i++) {
            if (objs[mod].get(i).getKey().equals(k)) {
                objs[mod].get(i).setValue(v);
                flag = 0;
                break;
            }
        }
        if (flag == 1) {
            objs[mod].add(new Node<K, V>(k, v));
        }

    }

    public V get(K k) {
        int mod = k.hashCode() % n;
        if (objs[mod] == null) {
            System.out.println(1);
            return null;
        }
        for (int i = 0; i < objs[mod].size(); i++) {
            if (objs[mod].get(i).getKey().equals(k)) {
                return objs[mod].get(i).getValue();
            }
        }
        return null;
    }

    public static void main(String[] args) {
     //自动拆包装以及Number和String自身已经重写了hashcode和equals方法 MyHashMap
<String, String> myHashMap = new MyHashMap<String, String>(); myHashMap.put("a", "A"); myHashMap.put("a", "AA"); myHashMap.put("b", "B"); myHashMap.put("b", "Bb"); System.out.println(myHashMap.get("a")); System.out.println(myHashMap.get("b")); MyHashMap<Object, Object> myHashMap1 = new MyHashMap<>(); myHashMap1.put(1, 11); myHashMap1.put(1, 111); System.out.println(myHashMap1.get(1)); } static class Node<K, V> { K key; V value; public K getKey() { return key; } public V getValue() { return value; } public void setValue(V value) { this.value = value; } public Node(K key, V value) { super(); this.key = key; this.value = value; } } }

重写hash码(内存泄漏问题)

public class HashCodeDivulge {
    private int x;
    private int y;
    public void setX(int x) {
        this.x = x;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        HashCodeDivulge other = (HashCodeDivulge) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }

    public static void main(String[] args) {
        HashCodeDivulge hashCodeDivulge1 = new HashCodeDivulge();
        HashCodeDivulge hashCodeDivulge2 = new HashCodeDivulge();
        System.out.println(hashCodeDivulge1.hashCode()==hashCodeDivulge2.hashCode());//true
        hashCodeDivulge2.setX(10);
        System.out.println(hashCodeDivulge1.hashCode()==hashCodeDivulge2.hashCode());//false
        //HashMap基于哈希值
        HashMap<? super HashCodeDivulge,Object> hashMap = new  HashMap<>();
        hashMap.put(hashCodeDivulge1, "AA");
        hashMap.put(hashCodeDivulge2, "BB");
        System.out.println(hashMap.size());
        //改变哈希值导致没移除掉
        hashCodeDivulge2.setX(11);
        hashMap.remove(hashCodeDivulge2);
        System.out.println(hashMap.size());
    }
}

HashTable  键和值都不能为null   线程安全的

LinkedHashMap 键不可重复,顺序基于插入的顺序,基于链表

Treemap:键可以排序,原理同TreeSet

5.队列

PriorityQueue 优先级队列,实现了Comparalbe接口

Queue  单向队列

Deque  双向队列

6.迭代器(iterator和Enumeration和ListIterator)

Iterator是Enumeration的升级版;

vector和hashtable用的迭代器是Enumeration;

hashmap,arraylist等的迭代器用是Iterator。

ListIterator是list集合特有的迭代器,可以在遍历的过程中对对元素的增、删、改、查的动作,而其他两个不能这么做

7.Properties

public class PopertiesDemo1 {
    public static void main(String[] args) {
        try {
            // 方式1:默认相对位置在工程目录下,src前面不能添加/
            FileInputStream fileInputStream = new FileInputStream("src/cn/collection/demo/config.properties");
            // 方式2:可以写相对位置默认在PopertiesDemo1.class相同的包下
            InputStream resourceAsStream = PopertiesDemo1.class.getResourceAsStream("config.properties");
            // 对方式2进行说明cn.collection.demo1.TestHashCode同包下,..上一级目录
            InputStream resourceAsStream2 = Class.forName("cn.collection.demo1.TestHashCode")
                    .getResourceAsStream("../../../cn/collection/demo/config.properties");
            // 工程目录可以用/表示src目录下,对方式2进行说明
            InputStream resourceAsStream3 = Class.forName("cn.collection.demo1.TestHashCode")
                    .getResourceAsStream("/cn/collection/demo/config.properties");
            // 方式3 默认在src下面,不能添加/
            InputStream resourceAsStream4 = PopertiesDemo1.class.getClassLoader()
                    .getResourceAsStream("cn/collection/demo/config.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream4);
            fileInputStream.close();
            resourceAsStream.close();
            resourceAsStream2.close();
            resourceAsStream3.close();
            resourceAsStream4.close();
            System.out.println(properties.getProperty("name"));
            properties.setProperty("name", "李四");
            System.out.println(properties.getProperty("name"));
            // 写入config1文件,在后面添加的模式
            FileWriter fileWriter = new FileWriter("config1", true);
            // "aa" 描述信息
            properties.store(fileWriter, "aa");
            fileWriter.close();
        } catch (Exception e) {
            System.out.println("没有找到文件");
        }
    }
}

8.其他

1)Weakhashmap

假如键为弱引用,垃圾回收机制下会被回收,用法和hashmap差不多。

2)IdentityHashMap

根据地址相同去重,用法和hashmap差不多。

3)Enummap

键必须是枚举值,用法和hashmap差不多。

4)Collections工具类常用方法

Sort()按照自然顺序排序

sort(List<T> list, Comparator<? super T> c)根据指定比较强排序

synchronized 保证线程安全

Empty    空容器可以避免空指针异常

Singleton    只包含一个元素的容器

Unmodifiable   不可变的容器

reverse(List<?> list) 反转顺序

猜你喜欢

转载自www.cnblogs.com/gg128/p/9321243.html