集合

集合类分2大类,Collection和Map,分别以单个方式存储和以键值对存储。
Collection的接口包括List、Set,其中Set接口本质上是调用了HashMap的Key部分。Collection是个抽象接口,常用方法包括add、remove、clear、indexOf、size、isEmpty、toArray等。重点方法是它的对象有个iterator方法,其返回类型包含hasNext()、next()和remove()方法,其中remove()的使用情况要特别留意,即不能出现在添加元素或者删除元素之后,否则会出现并发修改异常。还有一个重点方法是contains(),如果引用类已经重写了equals()方法,那么只要对象的引用是一致的,contains都会判断为true,否则为false。
Map接口存储的key和value都是引用数据类型,常用方法包括clear、containsKey、containsValue、isEmpty、keySet、put、remove、size、values、entrySet。Map接口的遍历很有意思,有3种遍历方式,包括迭代器、foreach和Map.Entry静态内部类。Map接口包括HashMap、Hashtable和SortedMap,其中Hashtable包括了一个属性类Properties类,SortedMap包含了TreeMap类。

List接口可以理解为线性表,其存储特点是有序可重复,它包括ArrayList、LinkedList和Vector。List的特有的常用方法包含set()和get()。
ArrayList底层是数组,初始容量是10,扩容机制是1.5倍,它的构造方法含有无参、带一个整型参数和带集合类的参数,无参表示默认初始大小为10,如果指定参数为100则表示初始容量改为100,带集合类表示可以将一个集合类的对象传进去,这样一来,比如一个Set集合就可以转成List集合。
LinkedList底层是一个双向链表,没啥可说的。
Vector类底层也是数组,不过它的方法基本上都带有synchronized关键字,表示这是线程安全的。既然是数组,就有初始容量和扩容机制,Vector类的初始容量是10,扩容机制是2倍。那么同样是数组,由于ArrayList是效率比较高,但毕竟是线程不安全的,如何将线程不安全的转成线程安全的呢?用集合类Collections(注意不是Collection)的synchronizedList方法,将List类对象传进去,即可变成线程安全的了。

Set集合可单纯理解为一种存储元素是无序且不重复的容器,这里的无序是指存入和取出的位序不是一样的。值得注意的是,放到Set集合子类中的元素实际上是放到Map集合子类的key部分了。Set的子类包括HashSet和SortedSet。
HashSet很普通,就是单纯地调用了HashMap的方法;而SoetedSet表示可排序的集合,大前提当然还是存入和取出位序不一,但是这个取出的顺序是指按照某种规则比如升序或降序输出元素。
TreeSet是SortedSet的典型代表,底层是二叉树,底层调用了TreeMap的各种方法,放到TreeSet集合中的元素,等同于放到TreeMap集合key部分。TreeSet无法对自定义类型进行排序,则会抛类型转换异常。这个解决办法有2个,其一就是将自定义类型实现Comparable接口并重写compareTo()方法,其二就是单独写一个类,实现Comparator接口。

Map集合存储的是元素的key-value值,key起主导作用,且key和value都是存储对象的内存地址。Map集合的特有方法包括keySet、put、values、entrySet。Map接口遍历的3种方式,迭代器、foreach和Map对象.entrySet,其中最后一种方式效率最高,因为key、value都是直接从node对象获取的。Map接口包括HashMap、Hashtable和SortedMap三种,其中Properties类是Hashtable的一个子类,同SortedSet一样,SortedMap也有一个TreeMap的子类。
HashMap是Map集合使用频率最高的一个类。HashMap从Java8后底层的数据结构变为数组+单向链表+红黑树了,即数组的初始容量是16,扩容机制是原来的2倍。如果单向链表中元素超过8个,单向链表这种数据结构会变成红黑树;当红黑树的节点数量小于6时,会重新把红黑树变成单向链表数据结构;当采用默认的数组大小为16时,如果红黑树中的元素过多,即三种数据结构的总数量超过了64,这个时候还在红黑树上思考如何扩容显得有些白费了,所以干脆所有的元素数量大于64时,就将数组扩容,扩充为原来的2倍。注意HashMap的几个重点方法:put、get、equals和hashCode,并且HashMap集合可以放key、value为空或key-value都为空的元素。
Hashtable是线程安全的map集合的子类,初始容量为11,负载因子是0.75,扩容机制为原来的2倍+1,Hashtable的key、value或key-value都不能为空,否则报空指针异常。Hashtable的子类Properties常被叫做属性类,是因为其key-value都作为键值对的属性,常用方法包括getProperty、load、setProperty。
SortedMap、TreeMapSortedSet、TreeSet极其类似,都是用于内部排序的类,当然还是符合无序、不重复的原则,只是无序是相对于添加进来的元素的位序是无序的。值得注意的是,当使用自定义类然后要遍历的话,会报类型转换异常,这是因为属性类没有规定比较的格式,有两种这样的实现方式,其一是实现Comparable接口,重写compareTo方法;其二是自己建一个类实现Comparator接口,重写compare方法。值得注意的是,在重写过程中当遇到String类型的要相互比较时,可以直接调用compareTo方法,因为String类已经重写了compareTo方法,不必自己再去重写。