list集合:存取有序,可以重复,有索引,允许存取多个Null元素
List接口继承Collection接口,实现了List接口的类称为List集合。可以使用Iterator取出所有元素,还可以使用get来获取指定下标的元素。
集合中不能定义基本数据类型,数组中可以定义基本数据类型和引用数据类型。
ArrayList底层是一个数组,当初始化ArrayList,数组的长度为0,第一次添加元素的时候,数组的长度为10,以后添加时,如果长度不够,按照1.5倍进行扩容,扩容之后将原数组中发的元素拷贝到新的数组中。11时开始扩容;
ArrayList集合的特点:底层是数组结构实现,查询快,增删慢
LinkedList集合的特点:底层是链表结构实现,查询慢,增删快
vector集合的特点:底层是数组结构实现,查询快,增删慢,线程安全,效率低
set集合:存取无序,不可重复
Treeset:
- 用TreeSet存储自定义对象,无参构造方法使用的自然排序对元素进行排序。让元素 所属的类实现Comparable接口,重写compareTo(T o)方法;
- 用TreeSet存储自定义对象,带参构造方法使用的是比较器排序,让集合构造方法接收Compartor的实现类对象,重写compare(T o1,T o2);
自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
TreeSet如何保证元素的唯一性:
调用compare To方法,小的存储在左边(负数),大的存储在右边(正数),相等就不存(0),从而保证元素的唯一性。
当我们new一个TreeSet的时候,实际上即使创建了一个TreeMap,并将这个TreeMap赋值给了TreeSet对象。而TreeMap底层是通过红黑树实现,故TreeSet底层也是通过红黑树(自平衡的二叉树);TreeSet的元素存储在TreeMap的key中,TreeMap的value是一个常量对象。
HashSet集合:
存取无序,不可存储重复元素,没有索引,不能使用普通for循环进行遍历和get方法。
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode方法来得到该对象的hashCode值,然后根据该值决定对象在集合中存储的位置,若此位置没有被存储对象就直接存储,如果已有对象则通过equals()比较两个对象是否相同,相同则不能添加,不同就将此元素挂在下面。
TreeSet集合的特点:底层是红黑树来存储数据。,不允许放入null值。
HashSet集合的特点:底层数据结构是哈希表,有且只能放入一个null值。JDK7哈希表=数组+链表;最多存12+15=27个值,28会发生扩容。竖12,横15个。
JDK8哈希表=数组+链表+红黑树;当节点个数少于等于8个时,采用数组+链表;当节点个数多于8个时,采用数组+红黑树;
存
Map集合:
HashMap底层是哈希表结构,依赖hashCode和equals方法保证键的唯一性。如果要存储自定义对象,需重写hashCode和equals方法。允许存空对象,允许键为null,因为键是唯一的,所以只能存储一个null值。
TreeMap底层是红黑树结构,依赖自然排序或者比较器排序,对键进行排序;如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象的时候给出比较器排序。
在这里插入图片描述
Map是两倍进行扩容。List是1.5倍。
怎样让arraylist线程安全?
既然ArrayList不是线程安全的,第一种很容易想到的方法就是使用synchronized来同步所有的ArrayList操作方法,JDK工具类为我们提供了。Collections.synchronizedList()方法其实底层也是在集合的所有方法之上加上了synchronized(默认使用的是同一个monitor对象,也可以自己指定)。
怎样让hashmap线程安全?
方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的. 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现.
方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进.