list集合、set集合的理解

  • List与set集合的区别

相同点:

        1.都是collection接口的子接口

        2.都是集合对象

不同点:

1.List集合是有序存储,Set集合是无序存储。这里的有序和无序针对的是存储地址来说的。

2.List可以存储重复的值,Set不可以存储重复的值.

 

  • 集合框架体系图:

  • ArrayList的实现原理

1.ArrayList   参考地址:https://www.cnblogs.com/leesf456/p/5308358.html

1)数组结构

2)类的继承关系

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

  说明:ArrayList继承AbstractList抽象父类,实现了List接口(规定了List的操作规范)、RandomAccess(可随机访问)、Cloneable(可拷贝)、Serializable(可序列化)。

3)ArrayList(int)构造函数

public ArrayList(int initialCapacity) {

        if (initialCapacity > 0) { // 初始容量大于0

            this.elementData = new Object[initialCapacity]; // 初始化元素数组

        } else if (initialCapacity == 0) { // 初始容量为0

            this.elementData = EMPTY_ELEMENTDATA; // 为空对象数组

        } else { // 初始容量小于0,抛出异常

            throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);

        }

   }

2. ArrayList()型构造函数

    public ArrayList() {

        // 无参构造函数,设置元素数组为空

        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

    }

  说明:当未指定初始化大小时,会给elementData赋值为空集合。

       说明:当传递的参数为集合类型时,会把集合类型转化为数组类型,并赋值给elementData。

       说明:指定elementData数组的大小,不允许初始化大小小于0,否则抛出异常。

4)添加数据时

ArrayList是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍。

ArrayList:线程不安全,查询速度快,增删速度慢;

       底层数据结构是数组结构

                 默认初始容量是10;

      扩容增量:原容量的 0.5倍

      如: ArrayList的容量为10,一次扩容后是容量为15

备注:获取容量的方法

public static int getCapacity(ArrayList arrayList) {

        try {

            Field elementDataField = ArrayList.class.getDeclaredField("elementData");

            elementDataField.setAccessible(true);

            return ((Object[]) elementDataField.get(arrayList)).length;

        } catch (NoSuchFieldException | IllegalAccessException e) {

            e.printStackTrace();

            return -1;

        }

    }

  • ArrayList和LinkedList的区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。 
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

  • hashmap的原理

https://www.cnblogs.com/leesf456/p/5242233.html

 

说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶(bucket)中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率。

1)HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

2)底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。

3)HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。

4)HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能

 

HashMap

         默认初始容量为16

         加载因子为0.75:即当HashMap中元素个数 超过数组长度的0.75倍 时,进行扩容

         扩容增量:原容量的 1 倍

         如 HashMap的容量为16,一次扩容后是容量为32

a.什么时候扩容

当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值,即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。

b.什么时候树形化

  执行树形化之前,会先检查数组长度,如果长度小于64,则对数组进行扩容,而不是进行树形化。

 

  • HashMap与HashTable的区别

hashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。

主要的区别有:线程安全性,同步(synchronization),以及速度。

1.HashMap可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行。

2.HashTable是线程安全的,ConcurrentHashMap是HashTable的替代,线程安全的。

3. 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

 

  • HashSet的原理

1)底层结构

因为HashSet底层是基于HashMap 或者 LinkedHashMap实现的,所以HashSet数据结构就是HashMap或者LinkedHashMap的数据结构

2)默认容量是16,加载因子是0.75

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_43154385/article/details/87860923