一、ArrayList

数组汇合利用

        // ArraysList 增删慢 查问快        // 依据源码 无参构造方法创立进去的是长度为0的数组{}        List<Integer> list = new ArrayList<>();        // 此时add办法进行源码扩容        list.add(100);        System.out.println(list.get(0));

add()办法扩容源码

    public boolean add(E e) {        // 不须要关注        modCount++;        // e对象 elementData汇合数组元素 size以后数组长度        add(e, elementData, size);        // 不论成功失败 均返回true        return true;    }        private void add(E e, Object[] elementData, int s) {        // 满足条件 进入扩容算法 不然就进行失常赋值操作        if (s == elementData.length)            elementData = grow();        elementData[s] = e;        size = s + 1;    }        private Object[] grow() {        // 至多须要加一个长度         return grow(size + 1);    }        private Object[] grow(int minCapacity) {        return elementData = Arrays.copyOf(elementData,                                           newCapacity(minCapacity));    }    private int newCapacity(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        // 新长度加上旧长度的0.5倍        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity <= 0) {            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)                // DEFAULT_CAPACITY 默认长度10                return Math.max(DEFAULT_CAPACITY, minCapacity);            // 超出最大二进制,符号会扭转,会变为正数            if (minCapacity < 0) // overflow                throw new OutOfMemoryError();            return minCapacity;        }                // MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8        return (newCapacity - MAX_ARRAY_SIZE <= 0)            ? newCapacity            : hugeCapacity(minCapacity);    }    private static int hugeCapacity(int minCapacity) {        if (minCapacity < 0) // overflow            throw new OutOfMemoryError();        return (minCapacity > MAX_ARRAY_SIZE)            ? Integer.MAX_VALUE            : MAX_ARRAY_SIZE;    }

二、LinkedList

        // LinkedList: 应用双向链表构造,增删快,查找慢        // (这种构造和ArrayList的数组构造正好是互补状态)        LinkedList<Integer> ll = new LinkedList<>();        // 模仿栈构造        // 压栈        ll.push(100);        ll.push(200);        // 弹栈        Integer i = ll.pop();        // 200        System.out.println(i);        // 1        System.out.println(ll.size());        // 上面正文参考 不倡议应用        // 增加汇合中第一个元素        // ll.addFirst(100);        // ll.addFirst(200);        // 移除汇合中第一个元素        // Integer removeData = ll.removeFirst();        // 200        // System.out.println(removeData);        // 1        // System.out.println(ll.size());

三、Vector

用法和ArrayList基本一致,是线程平安的。

        // 10 初始化长度 20 扩容增量 此处是相较于ArrayList不同之处        List<Integer> v = new Vector<>(10, 20);        v.add(100);        v.add(200);

四、Iterator和ListIterator

        // Iterator 迭代器 作用遍历汇合        // Iterator迭代Collection下List和Set ListIterator迭代List上面的汇合        List<Integer> list = new ArrayList<>();        list.add(1);        list.add(2);        list.add(3);        list.add(4);        list.add(5);        Iterator<Integer> iterator = list.iterator();        iterator.next();        // 必须要有值能力移除即后面调用next()办法,当然没值也会报错        iterator.remove();;        // 4        System.out.println(list.size());        // 判断迭代器下个是否有值        while(iterator.hasNext()) {            // 迭代器往下走,并取值            Integer i = iterator.next();            // 输入 2 3 4 5            System.out.println(i);        }        // 用法和iterator差不多        ListIterator<Integer> listIterator = list.listIterator();        // 获取向上走的值        listIterator.hasPrevious();        // 增加        listIterator.add(10);        // 设置        listIterator.next();        listIterator.set(200);        listIterator.previous();        // 5        System.out.println(list.size());        while(listIterator.hasNext()) {            // 输入 200 3 4 5            System.out.println(listIterator.next());        }

五、Set

Set汇合是没有反复的元素,包含null只会存在一个

5.1 HashSet

        // HashSet是散列寄存的数据结构(哈希表)        // 实质是 map = new HashMap<>()        // 因为曾经存在双值存储的哈希表 所以这边反复利用了造成当初的单值存储的哈希表        Set<String> set = new HashSet<>();        // map.put(e, PRESENT)        set.add("人有酸甜苦辣");        set.add("月有阴晴圆缺");        set.add("但愿人长久");        set.add("但愿人长久");        set.add("千里共婵娟");        set.add("千里共婵娟");        Iterator<String> iterator = set.iterator();        while (iterator.hasNext()) {            System.out.println(iterator.next());        }

5.2 TreeSet

    public static void main(String[] args) {        // TreeSet 应用二叉树进行存储的 有序(天然程序)        Set<Person> set = new TreeSet<>();        Person p1 = new Person("张三", 13);        Person p2 = new Person("李四", 14);        Person p3 = new Person("麻五", 14);        set.add(p1);        set.add(p2);        set.add(p3);        // 遍历前需制订本人的排序规定, 否则可能报错        // Person{name='张三', age=13}        // Person{name='李四', age=14}        // 比拟规定雷同的值,不被贮存        for (Person p : set) {            System.out.println(p);        }        // set.add("C");        // set.add("B");        // set.add("A");        // set.add("D");        // A B C D        // Iterator<String> iterator = set.iterator();        // while(iterator.hasNext()) {        //    System.out.println(iterator.next());        // }    }    static class Person implements Comparable<Person> {        private String name;        private int age;        @Override        public int compareTo(Person o) {            // this与0比拟            // 返回this小/0/大            if (this.age > o.age) {                return 1;            } else if (this.age == o.age) {                return 0;            }            return -1;        }        public Person(String name, int age) {            this.name = name;            this.age = age;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public int getAge() {            return age;        }        public void setAge(int age) {            this.age = age;        }        @Override        public String toString() {            return "Person{" +                    "name='" + name + '\'' +                    ", age=" + age +                    '}';        }    }

六、Map

Map(Mapping 映射)汇合存储的是 键值对 数据,Map的键不可反复。
影响HashMap的实例化性能的是初始容量和负载因子。
HashMap/Hashtable/ConcurrentHashMap TreeMap/LinkedHashMap应用办法基本一致。

HashMap是线程不平安,效率高。HashTable线程平安, 效率低。
ConcurrentHashMap采纳分段锁机制,保障线程平安,效率较高。

TreeMap是有序的排。
LinkedHashMap存储有序。

6.1 HashMap

        Map<String, String> map = new HashMap<>();        // 存值        map.put("k1", "v1");        // 取值 v1        System.out.println(map.get("k1"));        map.put("k2", "v2");        // 遍历        Set<String> set = map.keySet();        for (String key : set) {            // k1->v1            // k2->v2            System.out.println(key + "->" + map.get(key));        }        // 转为Collection汇合        Collection<String> c = map.values();        for (String s : c) {            System.out.println(s);        }

HashMap源码粗解析

    // 构造方法    public HashMap() {        // 默认加载因子0.75f        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted    }    public V put(K key, V value) {        // 先计算键的hash值,而后调用putVal        return putVal(hash(key), key, value, false, true);    }    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                   boolean evict) {        // n是桶(数组)的长度        Node<K,V>[] tab; Node<K,V> p; int n, i;        // table是默认的16个长度的数组赋值给tab        if ((tab = table) == null || (n = tab.length) == 0)            // resize扩容算法 n扩容之后的长度            n = (tab = resize()).length;        // (n - 1) & hash 是取余后的长度   数组下标没有值间接赋值        if ((p = tab[i = (n - 1) & hash]) == null)            tab[i] = newNode(hash, key, value, null);        else {            Node<K,V> e; K k;            // key存在新值笼罩老值            if (p.hash == hash &&                ((k = p.key) == key || (key != null && key.equals(k))))                e = p;            // 判断是树节点 按红黑树套路进行存储             else if (p instanceof TreeNode)                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);            // 链表套路进行赋值            else {                for (int binCount = 0; ; ++binCount) {                    // 非反复值操作                    if ((e = p.next) == null) {                        p.next = newNode(hash, key, value, null);                        // 这边是二叉树操作                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                            treeifyBin(tab, hash);                        break;                    }                    // 反复值操作                    if (e.hash == hash &&                        ((k = e.key) == key || (key != null && key.equals(k))))                        break;                    p = e;                }            }            // 后面e被赋值,进入此办法            if (e != null) { // existing mapping for key                V oldValue = e.value;                if (!onlyIfAbsent || oldValue == null)                    e.value = value;                afterNodeAccess(e);                return oldValue;            }        }        // 减少批改次数        ++modCount;        // 判断是否到了临界值        if (++size > threshold)            // 扩容            resize();        afterNodeInsertion(evict);        return null;    }

总结

在文章的最初作者为大家整顿了很多材料!包含java外围知识点+全套架构师学习材料和视频+一线大厂面试宝典+面试简历模板+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书等等!
欢送关注公众号:前程有光,支付!