集合专题

二、容器

18.java 容器都有哪些?

Collection:

  list:

    arraylist: 数组实现,线程不安全,查询快,默认长度10,元素个数超过容量,扩容1.5倍+1

    linkedlist: 链表实现,线程不安全,插入删除快,双向链表,没有初始化值,也没有扩容机制

    vector:数组实现,线程安全,默认长度10,元素个数超过容量,扩容2倍

 

  set:

    hashset:基于hashmap实现,value值固定为object不重复,默认长度16,元素个数超过容量75%扩容,扩容2倍

      linkedhashset:

    treeset:二叉树实现

    

Map:

  hashmap:entry数组加链表实现,线程不安全,默认长度16,默认长度16,元素个数超过容量75%扩容,扩容2倍

    linkedhashmap:链表加hash表实现

    WeakHashMap

  

  treemap:红黑树实现

    identifyHashMap

19.Collection 和 Collections 有什么区别?

Collection是集合接口,Collections是工具类。

 

20.List、Set、Map 之间的区别是什么?

list/set是单列集合,map是双列集合

list有序 可重复

set无序 不可重复

 

21.HashMap 和 Hashtable 有什么区别?

hashmap线程不安全,

Hashtable线程安全,效率低

 

22.如何决定使用 HashMap 还是 TreeMap?

 

 

23.说一下 HashMap 的实现原理?

数组和链表的结合

hashmap里放的是Entry数组,每个entry对象里有一条链表,链的每个节点上有key/value/next

put/get:通过hash算法计算放在entry数组index,找到链,再通过equals计算在链上面的位置

public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            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;
                }
            }
            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;
    }
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

 

 

 

24.说一下 HashSet 的实现原理?

add方法调用的hashmap的put方法,value是固定的Object PRESENT = new Object()对象。不存在key则插入,存在则不保存。

 

25.ArrayList 和 LinkedList 的区别是什么?

Arraylist是数组实现,查询快

linkedlist是双向链表,删除新增快

数组:

静态分配内存,需要连续的空间,浪费内存;大小固定,不能动态拓展

查询的时间复杂度是o(1)(一个常量,时间不随数据量的变化而增大);插入删除的时间复杂度是o(n)(数据量扩大n倍,时间扩大n倍);

 

链表:

动态分配内存,不需要连续的空间,节约内存;大小不固定,比较灵活;

查询需要从头开始往后查,查询的时间复杂度是0(n),插入删除的时间复杂度是o(1);

 

 

26.如何实现数组和 List 之间的转换?

String[] strs = new String[] {"aaa", "bbb", "ccc"};
数组转list,List<String> list = Arrays.asList(strs);
list转数组,String[] str = list.toArray(new String[]{list.size()});

 

27.ArrayList 和 Vector 的区别是什么?

 

28.Array 和 ArrayList 有何区别?

 

 

29.在 Queue 中 poll()和 remove()有什么区别?

30.哪些集合类是线程安全的?

31.迭代器 Iterator 是什么?

32.Iterator 怎么使用?有什么特点?

33.Iterator 和 ListIterator 有什么区别?

34.怎么确保一个集合不能被修改?

posted @ 2021-02-24 10:25  三灶龙都88  阅读(32)  评论(0)    收藏  举报