Java集合基础知识

Java集合框架基础:
在这里插入图片描述

Collection为集合层级的根接口,集合中包含一组对象。

Set是一个不能包含重复元素的集合;List是一个有序集合,可以包含重复元素;

Map是一种key-value结构的集合模型,不能包含重复的key值,每个key只能映射到一个value。

HashMap和HashTable的不同:

a. HashMap允许key和value为null, 而HashTable不允许

b. HashTable是线程同步的,而HashMap不是。因此HashMap适合单线程环境,HashTable适合多线程环境(具体应用要根据场景需求,而不是谁适合谁不适合,在不需要线程同步限制的时候推荐使用HashMap,可以提高程序运行的效率)

c. LinkedHashMap是HashMap的一个子类,如需遍历顺序,可以很方便的从HashMap转向LinkedHashMap,而HashTable它的顺序是不可知的

d. HashMap提供退key的Set进行遍历,因此它是fail-fast的,单HashTable提供对key的Enumeration进行遍历,不支持fail-fast

e. HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap

补充: HashMap可以通过Map m = Collections.synchronizedMap(hashMap)来达到同步的效果。

HashMap还是TreeMap:

a. HashMap的内部结构是一个数组,线性顺序存储,二次结构使用线性的单链表。 使用key的hash code做二次hash之后,在截取小于数组长度的值为索引。

b. HashMap是一个常用的Map,它根据键的hashcode值存储数据,根据key可以快速获取value,具有很快的访问速度。只允许一个key值为null,不支持线程同步,如果需要同步可以使用Collections的synchronizedMap方法实现

c. TreeMap其内部数据结构是一棵红黑树,使用链式存储,可以指定比较器Comparator, key需实现Comparable接口。key值不能为null。存节点性能稍差,因为需要调整树结构;取节点用的链表遍历,但是属于有序比较,性能中等。

ArrayList和Vector的相同与不同:

a. 两者都是基于索引的,基于数组来实现的

b. 两者都维护插入的顺序,可以根据插入顺序来获取元素

c. 两者的迭代器都是fail-fast的

(fail-fast机制是Java集合Collection中的一种错误机制,当多个线程对同一个集合的内容进行操作时就可能产生fail-fast事件。例如线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程更改了,那么线程A访问集合时就会抛出 CocurrentModificationException,产生fail-fast事件)

d. 两者都允许null值,可以利用索引对元素进行随机的访问

e. Vector是同步的,而ArrayList不是。如果你寻求在迭代时对列表进行改变,你应该使用CopyOnWriteArrayList

f. ArrayList更加通用,可以使用Collections工具类轻易的获取同步列表和只读列表

ArrayList和LinkedList异同:

a. 两者都是List接口的具体实现,ArrayList基于动态数组,LinkedList基于链表的数据结构

b. ArrayList是基于Array实现,一个基于索引的数据结构,所以它可以对元素进行随机访问,复杂度为O(1)。LinkedList存储一些列的节点数据,每个节点都与前一个和下一个节点相连。所以尽管有使用索引来获取元素的方法,其内部实现是从起点开始遍历,遍历到所以的节点后返回元素,时间复杂度为O(n), 比ArrayList要慢

c. 与ArrayList相比,在LinkedList中插入、删除一个元素会更快,因为在插入或删除一个元素的时候ArrayList需要更新每个元素的索引(插入不代表在最后添加新元素),并改变数组的大小, 而LinkedList仅仅需要在更新插入位置前后两个元素的节点信息

d. LinkedList需要消耗更多的内存,因为它需要同时存储每个节点前后节点的引用

补充:LinkedList实现了List接口,允许null值。此外它还提供额外的get/remove/insert方法在LinkedList的首部或尾部。这些操作可以使LinkedList被用作堆栈(stack)/ 队列(queue)或双向队列 (queue)。 LinkedList没有同步方法,如果多个线程同事访问一个list则必须实现访问同步, 通过: List list = Collections.synchronizedList(new LinkedList(…)) 实现

Array与ArrayList异同:

a. Array可以包含基本数据类型或对象类型,ArrayList只能包含对象类型

b. Array的大小固定,ArrayList的大小是动态变化的,一次默认增加原大小的0.5倍

c. ArrayList提供了更多的方法和特性

Collections类解析:

Java.util.Collections是一个工具类,仅包含静态方法,它们操作或返回集合。包含操作集合的多态算法,返回一个由指定集合支持的新集合和其他一些内容。包含集合框架算法的方法,比如折半搜索、排序、混编和逆序等

Comparator与Comparable接口:

两者的作用是对自定义的Class进行大小比较

例如: public class Man{public String name; public int age;}, 实例化后得到包含 man1, man2, man3的manList。我们用 Collections.sort(manList),得不到我们预期排序的结果。但是如果是一个包含的字符串的listStr,通过调用 Collections.sort(listStr) 是可以得到正确的排序,主要是因为 String 已经实现了 Comparable 接口。 因此 Man 也需要实现一个比较器才能进行manList的排序。

Comparable 是定义在 Man 类的内部: public class Man implements Comparable {…},集成 Comparable,实现 compareTo 方法

Comparator 是定义在 Man 外部的, Man 类本身不需要有任何变化,但是我们需要另外定义一个比较器: public ManComparator implements Comparator {…}

在 ManComparator 内部实现了怎么比较两个 Man 的大小,在对一个 manList 进行排序的时候: Collections.sort(manList, new ManComparator())