杨明翰的Java教学系列之集合框架篇V0.2(持续更新)

it2025-12-24  7

文章目录

传送门前言什么是集合框架集合框架体系Collection接口`Set接口``HashSet`LinkedHashSet TreeSetEnumSet Queue接口PriorityQueueDeque接口 `List接口``ArrayList`LinkedListVector `Map接口``HashMap``LinkedHashMap` HashtableTreeMapWeakHashMapIdentityHashMapEnumMap Collections总结


传送门

杨明翰的Java教学系列之认识Java篇

杨明翰的Java教学系列之基础语法篇

杨明翰的Java教学系列之初级面向对象篇

杨明翰的Java教学系列之数组篇

杨明翰的Java教学系列之进阶面向对象篇

杨明翰的Java教学系列之异常篇

杨明翰的Java教学系列之集合框架篇


前言

存储若干对象到集合中,类似于数组的升级版, 可以对集合中的对象进行存取、遍历等等操作。

集合是非常有用的知识点, 在后面会用到从数据库中查询出来的数据, 返回给我们来使用, 那些数据库中的数据就可以存储在集合之中。


什么是集合框架

Java集合框架提供了一套性能优良,使用方便的接口和类, Java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包。

集合框架是一个用来代表和操纵集合的统一架构, 除了集合,该框架也定义了几个Map接口和类。

Map里存储的是[键/值]对,尽管Map不是Collection, 但是它们完全整合在集合中, 集合框架的类和接口均在java.util包中。

所有的集合框架都包含如下内容:

接口,代表集合的抽象数据类型,只是定义没有实现,接口允许实现类来为其实现细节;

实现(类),是集合接口的具体实现,从本质上讲,它们是可重复使用的数据结构;

算法,是实现集合接口的对象里的方法执行的一些有用的计算。例如:搜索和排序,相同的方法可以在相同的接口上有着不同的实现;

整个集合框架就围绕一组标准接口而设计。 你可以直接使用这些接口的标准实现, 诸如: LinkedList、HashSet、TreeSet等, 除此之外你也可以通过这些接口实现自己的集合。


集合框架体系

集合体系又分为两大分支, 分别为Map接口分支与Collection接口分支。

Map接口与Collection接口是两个接口,千万不要弄混, Map接口的应用非常广泛,主要用于存储KV结构数据, 这两张图需要牢记并且能拥有徒手画图的能力。

虚线:实现接口 实线:继承父类 箭头方向:子类指向父类&实现类指向接口

Collection接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WxG5gY4m-1603362650508)(evernotecid://85A94EB2-9BD2-45DE-A16D-D9C9CD7ECF0B/appyinxiangcom/12192613/ENResource/p298)]

Collection是最基本的集合接口, Java不提供直接继承自Collection的类, 只提供继承于的子接口(如List和Set等)。

Collection接口是List、Set、Queue接口的父接口, 该接口里定义的方法可以被子接口所使用。

方法描述boolean add(Object o)该方法用于向集合里添加一个元素。如果集合对象被添加操作改变了,则返回true。boolean addAll(Collection c)该方法把集合c里的所有元素添加到指定集合里,如果集合对象被添加操作改变了,则返回true。void clear()清除集合里的所有元素,将集合长度变为0。boolean contains(Object o)返回集合里是否包含指定元素。boolean containsAll(Collection c)返回集合里是否包含集合c里的所有元素。

Set接口

Set是Collection的子接口,Set保存无序的、不可重复的元素。

Set检索效率低下,删除和插入效率高, 插入和删除不会引起元素位置改变。

LinkedHashSet的元素有序(插入顺序), TreeSet的元素有序(比较顺序)。

HashSet的性能总是比TreeSet好, 只有当需要保持排序的Set时, 才应该使用TreeSet,否则都应该使用HashSet。

EnumSet是性能最好的,但是只能保存枚举类型, HashSet,TreeSet,EnumSet都是线程不安全的。

HashSet

HashSet类实现了Set接口,不允许出现重复元素, 不保证集合中元素的顺序,允许包含值为null的元素, 但最多只能一个。

HashSet不是同步的,线程不安全, 如果多个线程同时访问一个HashSet, 并同时修改了HashSet集合时, 必须通过代码来保证其同步。

如果HashSet中两个以上的元素具有相同的hashCode值, 将会导致性能下降。

hash算法的功能: 它能保证通过一个对象快速查找到另一个对象, hash算法的价值在于速度,它可以保证查询被快速执行。

当需要查询集合中的某个元素时, hash算法可以直接根据该元素的值计算出该元素的存储位置,从而让程序快速定位该元素的存储位置。

Set没有顺序且不允许相同的对象添加进集合, 判断标准是使用euqals而不是==, 还有hashCode双重判断,需要注意! HashSet按Hash算法来存储集合中的元素, 具有很好的存储和查找性能。

LinkedHashSet

LinkedHashSet是HashSet的子类, 它使用链表维护元素的次序, 这使得元素看起来是以插入的顺序保存的。

因为LinkHashSet需要维护顺序, 因此性能上略低于HashSet, 但在迭代访问Set里的全部元素时将有很好的性能。

TreeSet

SortedSet接口继承于Set保存有序的集合, TreeSet是SortedSet接口的实现类,可以实现排序等功能。

TreeSet采用红黑树的数据结构来存储集合元素, TreeSet支持两种排序方法:自然排序和定制排序。

在默认情况下,TreeSet采用自然排序。

TreeSet会调用集合元素的compareTo(Object obj)方法, 来比较元素之间的大小关系,然后将集合元素按升序排列, 这种方式就是自然排序。

Java提供了一个Comparable接口, 该接口里定义了一个compareTo(Object obj), 该方法返回一个整数值, 实现该接口的类必须实现该方法, 实现了该接口的类的对象就可以比较大小。

如果试图把一个对象添加到TreeSet时, 则该对象的类必须实现Comparable接口, 否则程序将会抛出一个异常。

如果两个对象通过compareTo(Object obj)比较相等, 新对象将无法添加到TreeSet集合中。

如果通过compareTo(Object obj)比较返回0, 则表示他们相等。

注意,equals相等也不相等了,必须要compareTo等于0才是相等。

在重写equals方法时候, 应该注意保证与compareTo方法由相同的结果。

TreeSet可以确保集合元素处于排序状态(按大小排序), 与HashSet相比,TreeSet还提供了几个额外的方法:

方法描述Comparator comparator()如果TreeSet采用了定制排序,则该方法返回定制排序所使用的Comparator,如果TreeSet采用了自然排序,则返回null。Object first()返回集合中第一个元素。Object last()返回集合中最后一个元素。Object lawer(Object e)返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是TreeSet集合里的元素)Object higher(Object e)返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,参考元素不需要是TreeSet集合里的元素)SortedSet subSet(fromElement,toElement)返回此Set的子集合,范围从formElement(包含)到toElement(不包含)。SortedSet headSet(toElement)返回此Set的子集,由小于toElement的元素组成。SortedSet tailSet(fromElement)返回此Set的子集,由大于或等于fromElement的元素组成。

EnumSet

EnumSet是一个专门为枚举类设计的集合类, EnumSet中的所有元素都必须是指定枚举类型的枚举值, 该枚举类型在创建EnumSet时显式或隐式的指定。

EnumSet的集合元素也是有序的, EnumSet以枚举值在Enum类内的定义顺序来决定集合元素的顺序。

EnumSet在内部以向量的形式存储, 这种存储形式非常紧凑,高效, 因此EnumSet对象占用内存很小,而且运行效率很好。 EnumSet不允许加入null元素。

方法描述static EnumSet allOf(Class elementType)创建一个包含指定枚举类里所有枚举值的EnumSet集合。static EnumSet complementOf(EnumSet s)创建一个其元素类型与指定EnumSet里元素类型相同的EnumSet集合,新EnumSet集合包含原EnumSet集合所不包含的、此枚举类剩下的枚举值(即新EnumSet集合和原EnumSet集合的集合元素加起来就是该枚举类的所有枚举值。)static EnumSet copyOf(Collection c)使用一个普通集合来创建EnumSet集合。static EnumSet copyOf(EnumSet s)创建一个与指定EnumSet具有相同元素类型、相同集合元素的EnumSet集合。static EnumSet noneOf(Class elementType)创建一个元素类型为指定枚举类型的空EnumSet。static EnumSet of(E first,E… rest)创建一个包含一个或多个枚举值的EnumSet集合,传入的多个枚举值必须属于同一个枚举类。static EnumSet range(E from,E to)创建一个包含从from枚举值到to枚举值范围内所有枚举值的EnumSet集合。

Queue接口

Queue用于模拟队列这种数据结构, 队列通常是指“先进先出”(FIFO)的容器。

方法描述void add(Object e)将指定元素加入此队列的尾部。Object element()获取队列头部的元素,但是不删除该元素。boolean offer(Object e)将指定元素加入此队列的尾部。当使用有容量限制的队列时,此方法通常比add(Object e)方法更好。Object peek()获取队列头部的元素,但是不删除该元素。如果此队列为空,则返回null。Object poll()获取队列头部的元素,并删除该元素。如果此队列为空,则返回null。Object remove()获取队列头部的元素,并删除该元素。

PriorityQueue

PriorityQueue保存队列元素的顺序, 是按队列元素的大小进行重新排序。

因此当调用peek()或者poll(), 取出队列中的元素时,并不是取出最先进入队列的元素, 而是取出队列中最小的元素。(违反了队列先进先出的原则)

PriorityQueue不允许插入null值, PriorityQueue的元素有两种排序方法: 自然排序:集合中的元素必须实现了Comparable接口, 而且应该是同一个类的多个实例。 定制排序:创建队列时,传入一个Comparator对象,该对象负责对队列中的所有元素进行排序。

Deque接口

Deque接口是Queue接口的子接口, Deque代表一个“双端队列”, 双端队列可以同时从两端来添加,删除元素, 因此Deque既可以当成队列使用,也可以当成栈使用。 Java为Deque接口提供了, ArrayDeque和LinkedList两个实现类。

ArrayDeque是Deque接口的实现类, 它是一个基于数组实现的双端队列。

方法描述void addFirst(Object e)将指定元素插入该双端队列的开头。void addLast(Object e)将指定元素插入该双端队列的末尾。Iterator descendingIterator()返回该双端队列对应的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。Object getFirst()获取但不删除双端队列的第一个元素。Object getLast()获取但不删除双端队列的最后一个元素。boolean offerFirst(Object e)将指定元素插入该双端队列的开头。boolean offerLast(Object e)将指定元素插入该双端队列的末尾。Object peekFirst(Object e)获取但不删除该双端队列的第一个元素;如果此双端队列为空,则返回null。Object peekLast(Object e)获取但不删除该双端队列的最后一个元素;如果此双端队列为空,则返回null。Object pollFirst(Object e)获取并删除该双端队列的第一个元素;如果此双端队列为空,则返回null。Object pollLast(Object e)获取并删除该双端队列的最后一个元素;如果此双端队列为空,则返回null。Object pop()(栈方法)pop出该双端队列所表示的栈的栈顶元素。相当于removeFirst()。void push(Object e)栈方法,将第一个元素push进该双端队列所表示的栈的栈顶。相当于addFirst(e)。Object removeFirst()获取并删除该双端队列的第一个元素。Object removeFirstOccurrence(Object o)删除该双端队列的第一次出现的元素o。void removeLast()获取并删除该双端队列的最后一个元素。void removeLastOccurrence(Object o)删除该双端队列的最后一次出现的元素o。

List接口

~Vector与Stack线程安全,但性能差。 ~ArrayList、LinkedList线程不安全。 ~LinkedList是双向链表,可做队列&栈。

List是Collection的子接口, List保存有序的、可重复的元素。 List和数组类似,可以动态增长, List中的每个元素都有其对应的顺序索引, 根据实际存储的数据的长度自动增长List的长度。

查找元素效率高,插入删除效率低, 因为会引起其他元素位置改变。

使用List能够精确的控制每个元素插入的位置, 能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素。

实现类有:ArrayList、LinkedList、Vector。

List作为Collection的子接口, 可以使用Collection的全部方法,还有一些新增的方法:

方法描述void add(int index,Object element)将元素element插入到List集合的index处。boolean addAll(int index,Collection c)将集合c所包含的所有元素都插入到List集合的index处。Object get(int index)返回集合index索引处的元素。int indexOf(Object o)返回对象o在List集合中第一次出现的位置索引。int lastIndexOf(Object o)返回对象o在List集合中最后一次出现的位置索引。Object remove(int index)删除并返回index索引处的元素。Object set(int index,Object element)将index索引处的元素替换成element对象,返回新元素。List subList(int fromIndex,int toIndex)返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合。List判断两个对象相等只要通过equals()方法比较返回true即可。boolean isEmpty()返回集合是否为空。当集合长度为0时返回true,否则返回false。Iterator iterator()返回一个Iterator对象,用于遍历集合里的元素。boolean remove(Object o)删除集合中的指定元素o,当集合中包含了一个或多个元素o时,这些元素将被删除,该方法将返回true。boolean removeAll(Collection c)从集合中删除集合c里包含的所有元素(相当于调用该方法的集合减集合c),如果删除了一个或一个以上的元素,该方法返回true。boolean retainAll(Collection c)从集合中删除集合c里不包含的元素(相当于把调用该方法的集合变成该集合和集合c的交集),如果该操作改变了调用调用该方法的集合,则该方法返回true。int size()该方法返回集合里元素的个数。Object[] toArray()该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素。

List接口中的contains是比较的内存地址。 注意,在使用contains之前,需要重写equals方法,例如:

public boolean equals(Object obj){ if (obj instanceof VcubeRoomStatusPerson) { VcubeRoomStatusPerson vcubeRoomStatusPerson = (VcubeRoomStatusPerson) obj; return this.participantTag.equals(vcubeRoomStatusPerson.getParticipantTag()) && this.participantName.equals(vcubeRoomStatusPerson.getParticipantName()) && this.participantType.equals(vcubeRoomStatusPerson.getParticipantType()); } return super.equals(obj); }

ArrayList

ArrayList是List接口的实现类,实现了可变大小的数组, 随机访问和遍历元素时,提供更好的性能。

ArrayList是线程不安全的,避免多线程环境下使用。

public class ArrayListDemo1 { public static void main(String[] args) { // 定义并创建一个ArrayList对象,list虽然允许存放不同类型的数据,但通常不建议这么做。 List<Integer> list1 = new ArrayList<Integer>(); // 判断list是否有元素 System.out.println(list1.isEmpty()); // 添加list元素 list1.add(5); for (int i = 0; i < 5; i++) { list1.add(i); } list1.add(2); System.out.println(list1); // 从list获取下标为x的元素 System.out.println(list1.get(1)); // 如果list中有此元素则返回该元素的下标(从0开始),否则返回-1 System.out.println("index==>" + list1.indexOf(2)); // 如果list中有此元素则返回最后一次出现的该元素的下标(从0开始),否则返回-1 System.out.println("index==>" + list1.lastIndexOf(2)); // list中元素个数 System.out.println("~~~" + list1.size() + "~~~"); // 删除list元素,允许按下标删和按元素删两种方式 list1.remove(new Integer(3)); // 指定位置添加元素,效率低,因为会把大家都往后移动。。。。 list1.add(0, 9); System.out.println(list1); // 指定位置添加元素,直接覆盖 list1.set(0, 8); System.out.println(list1); // list转数组 Integer[] xxx = list1.toArray(new Integer[] {}); for (Integer a : xxx) { System.out.println("array===>" + a); } // list添加另外一个list List<Integer> list2 = new ArrayList<Integer>(); list2.add(10); list2.add(11); list2.add(12); list1.addAll(list2); System.out.println(list1); // 切分出一个子list,类似于String的substring() List<Integer> subList1 = list1.subList(0, 3); System.out.println("subList1=" + subList1); // list中是否包含某个元素 if (list1.contains(2)) { System.out.println("2 yes"); } else { System.out.println("2 no"); } // 注意,此处我删掉了list里的一个元素,这个元素原本是属于list2的,然后containsAll就失败了。 list1.remove(new Integer(5)); if (list1.containsAll(list2)) { System.out.println("list2 yes"); } else { System.out.println("list2 no"); } // 其实在list1中的list2已经不完整了,但是也能把剩余的全部干掉。 list1.removeAll(list2); System.out.println(list1); list1.add(1); List<Integer> list3 = new ArrayList<Integer>(); list3.add(1); // 只保留参数与list1的交集,即1;list是3,2,1,参数是1,则保留1。如果list是1,参数是3,2,1则返回false,没有变化。 System.out.println(list1.retainAll(list3)); System.out.println(list1); // 清空list list1.clear(); System.out.println(list1); // list的四种遍历方式 List<String> list4 = new ArrayList<String>(); list4.add("A"); list4.add("B"); list4.add("C"); // 第1种使用foreach遍历List for (String str : list4) { // System.out.println(str); } // 第2种使用原始for for (int i = 0; i < list4.size(); i++) { System.out.println(list4.get(i)); } // 第3种使用迭代器进行相关遍历 Iterator<String> ite = list4.iterator(); while (ite.hasNext()) { System.out.println(ite.next()); } // 第4种使用JDK8的Lambda list4.forEach(item->System.out.println(item)); } }

LinkedList

LinkedList是List接口的实现类, 它是一个基于链表实现的List类, 对于顺序访问集合中的元素进行了优化,特别是插入, 删除元素的时候速度非常快, 但是随机访问集合元素时性能较差。

LinkedList既实现了List接口,也实现了Deque接口, 由于实现了Deque接口,可以被当成双端队列来使用, 也可以作为栈来使用。

该类实现了List接口,允许有null(空)元素。

主要用于创建链表数据结构,该类没有同步方法, 如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。

public class LinkedListDemo1 { public static void main(String[] args) { // 创建并初始化链表,LinkedList既可以当队列也可以当栈 LinkedList<String> books = new LinkedList<>(); // 加入到链表的头部 books.push("a"); // 加入到栈的尾部,注意此处不会因为写在前面就放在链表的前面 books.offer("b"); // 加入到链表的头部(最后加的放在链表的最上面) books.offerFirst("c"); //加入到链表的尾部 books.addLast("d"); //加入到链表的尾部 books.addLast("e"); //加入到链表的尾部 books.addLast("f"); //从 头删除一个链表元素 books.removeFirst(); //从 尾删除一个链表元素 books.removeLast(); // 遍历链表 for (int i = 0; i < books.size(); i++) { System.out.println(books.get(i)); } // 访问但不删除栈顶的元素 System.out.println(books.peekFirst()); // 访问但不删除队列的最后一个元素 System.out.println(books.peekLast()); // 将栈顶的元素弹出栈 System.out.println(books.pop()); // 访问并删除队列的最后一个元素 System.out.println(books); System.out.println(books.pollLast()); System.out.println(books); System.out.println("----------"); //可以给定一个Collection作为参数来创建链表 List<String> list = new ArrayList<>(); list.add("g"); list.add("h"); list.add("i"); LinkedList<String> books2 = new LinkedList<>(list); System.out.println(books2); } }

Vector

该类和ArrayList非常相似,但是该类是同步的, 可以用在多线程的情况,该类允许设置默认的增长长度, 默认扩容方式为原来的2倍。

Stack是Vector的一个子类, 它实现了一个标准的后进先出的栈。

未完待续

Map接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Azpm4HyA-1603362650512)(evernotecid://85A94EB2-9BD2-45DE-A16D-D9C9CD7ECF0B/appyinxiangcom/12192613/ENResource/p299)]

Map接口将唯一的键映射到值,用于存储[键/值]映射关系, [键/值]=[key/value],使用key可以找到value, 例如: key=5,value=user5对象; key=6,value=user6对象;

方法描述void clear()删除该Map对象中所有key-value对。boolean containsKey(Object key)查询Map中是否包含指定的key,如果包含则返回true。boolean containsValue(Object value)查询Map中是否包含一个或多个value,如果包含则返回true。Set entrySet()返回Map中包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry(Entry是Map的内部类)对象。Object get(Object key)返回指定key所对应的value;如果此Map中不包含该key,则返回null。boolean isEmpty()查询该Map是否为空(即不包含任何key-value对),如果为空则返回true。Set keySet()返回该Map中所有key组成的Set集合。Object put(Object key,Object value)添加一个key-value对,如果当前Map中已有一个与该key相等的key-value对,则新的key-value对会覆盖原来的key-value对。void putAll(Map m)将指定Map中的key-value对复制到本Map中。Object remove(Object key)删除指定key所对应的key-value对,返回被删除key所关联的value,如果该key不存在,则返回null。int size()返回Map里的key-value对的个数。Collection values()返回该Map里所有value组成的Collection。

Map中包含了一个内部类Entry, Map.Entry,描述在一个Map中的一个元素(键/值对)。

该类封装了一个key-value对,方法如下:

方法描述Object getKey()返回该Entry里包含的key值。Object getValue()返回该Entry里包含的value值。Object setValue(V value)设置该Entry里包含的value值,并返回新设置的value值。

HashMap

HashMap是一个散列表,实现了Map接口, 它存储的内容是键值对(key-value)映射, key-value可为null,无序,性能较高,线程不安全。

HashMap查找数据非常快, 它并不是像ArrayList那样一个挨着一个的找, 而是使用[hash code/哈希码]来查找数据。

在HashMap的构造方法中, 可以设定hash表的capacity与load factor, 用来调节性能参数。

判断2个key是否相等, 也需要equals()+hashCode()双验证, 在使用containsValue()时, 只要2个对象通过equals()返回true即可判断。

public class HashMapDemo2 { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); // 第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= " + key + " and value= " + map.get(key)); } // 第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第三种:推荐,尤其是容量大时 System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第四种 System.out.println("通过Map.values()遍历所有的value,但不能遍历key"); for (String v : map.values()) { System.out.println("value= " + v); } // 第五种JDK8 map.forEach((k, v) -> { System.out.println(k + " " + v); }); } }

LinkedHashMap

LinkedHashMap使用双向链表, 来维护key-value对的顺序(其实只需要考虑key的顺序), 顺序与key-value对的插入顺序保持一致。

Map<String,Object> m = new LinkedHashMap(); //按顺序来的 m.put("1", 1); m.put("2", 2); m.put("3", 3); //遍历MAP for (String key : m.keySet()) { System.out.println("key= "+ key + " and value= " + m.get(key)); }

注意: 在修改map里的数据的时候,如果修改完之后, 不再put,那就不会存上。

Hashtable

Hashtable是Dictionary(字典) 类的子类, 位于java.util包中。

Hashtable的元素不为null,无序,线程安全, HashMap比Hashtable要快一点。

未完待续

TreeMap

TreeMap是基于红黑树数据结构的实现, 每个key-value对即作为红黑树的一个节点, TreeMap存储key-value对(节点)时, 需要根据key对节点进行大小排序(比较顺序)。

TreeMap可以保证所有的key-value对处于有序状态,TreeMap有两种排序方式:

自然排序,TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象;

定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。采用定制排序时不要去Map的key实现Comparable接口;

TreeMap中判断2个key相等的标准是: 2个key通过compareTo()方法返回0, 如果key是自定义类,则需要重写equals方法, 让equals和compareTo保持一致。

SortedMap接口继承于Map接口,使Key保持在升序排列。

TreeMap比HashMap、Hashtable要慢, 尤其在插入,删除key-value对时更慢。

方法描述Map.Entry firstEntry()返回该Map中最小key所对应的key-value对,如果该Map为空,则返回null。Object firstKey()返回该Map中的最小key值,如果该Map为空,则返回null。Map.Entry lastEntry()返回该Map中最大key所对应的key-value对,如果该Map为空或不存在这样的key-value对,则都返回null。Object lastKey()返回该Map中的最大key值,如果该Map为空或不存在这样的key,则都返回null。Map.Entry higherEntry(Object key)返回该Map中位于key后一位的key-value对(即大于指定key的最小key所对应的key-value对),如果该Map为空,则返回null。Map.Entry lowEntry(Object key)返回该Map中位于key前一位的key-value对(即小于指定key的最大key所对应的key-value对),如果该Map为空,则返回null。Object higherKey(Object key)返回该Map中位于key后一位的key值(即大于指定key的最小key值)。如果该Map为空或不存在这样的key-value对,则都返回null。Object lowKey(Object key)返回该Map中位于key前一位的key值(即小于指定key的最大key值)。如果该Map为空或不存在这样的key-value对,则都返回null。NavigableMap subMap(Object fromKey,boolean fromInclusive,Object toKey,boolean toInclusive)返回该Map的子Map,其key的范围是从fromKey(是否包括取决于第二个参数)到toKey(是否包括取决于第四个参数)。SortedMap subMap(Object fromKey,Object toKey)返回该Map的子Map,其key的范围是从fromKey(包括)到toKey(不包括)。SortedMap tailMap(Object fromKey)返回该Map的子Map,其key的范围是大于fromKey(包括)的所有key。SortedMap headMap(Object toKey)返回该Map的子Map,其key的范围是小于toKey(不包括)的所有key。NavigableMap tailMap(Object fromKey,boolean inclusive)返回该Map的子Map,其key的范围是大于fromKey(是否包括取决于第二个参数)的所有key。NavigableMap headMap(Object toKey,boolean inclusive)返回该Map的子Map,其key的范围是小于toKey(是否包括取决于第二个参数)的所有key。

WeakHashMap

当某个对象在WeakHashMap中充当key时, 在其他地方都没有引用这个对象的话, 那么这个对象可能会被当做垃圾进行GC。

当GC回收了该key所对应的实际对象之后, WeakHashMap会自动删除该key对应的key-value对。

IdentityHashMap

IdentityHashMap用而非equals()比较key, 当2个key严格相等(key1key2)时, IdentityHashMap才认为2个key相等。

未完待续

EnumMap

EnumMap是一个与枚举类一起使用的Map实现, EnumMap中的所有key都必须是单个枚举类的枚举值, 创建EnumMap时必须显式或者隐式指定它对应的枚举类。

EnumMap根据key的自然顺序, 即枚举值在枚举类中的定义顺序,来维护key-value对的顺序。

EnumMap不允许使用null作为key,但允许null作为value。

EnumMap的性能最好,但只能用于枚举值作为key。


Collections

排序操作:

方法没事static void reverse(List list)反转指定List集合中元素的顺序。static void shuffle(List list)对List集合元素进行随机排序。static void sort(List list)根据元素的自然顺序对指定List集合的元素按升序进行排序。static void sort(List list,Comparator c)根据指定Comparator产生的顺序对List集合元素进行排序。static void swap(List list,int i,int j)将指定List集合中的i处元素和j处元素进行交换。static void rotate(List list,int distance)当distance为正数时,将list集合的后distance个元素“整体”移到前面,当distance为负数时,将list集合的前distance个元素“整体”移到后面。该方法不会改变集合的长度。

查找,替换:

方法描述static int binarySearch(List list,Object key)使用二分搜索法搜索指定的List集合,以获得指定对象在List集合中的索引。如果要使该方法可以正常工作,则必须保证List中的元素已经处于有序状态。static Object max(Collection coll)根据元素的自然排序,返回给定集合中的最大元素。static Object max(Collection coll,Comparator comp)根据Comparator指定的顺序,返回给定集合中的最大元素。static Object min(Collection coll)根据元素的自然排序,返回给定集合中的最小元素。static Object min(Collection coll,Comparator comp)根据Comparator指定的顺序,返回给定集合中的最小元素。static void fill(List list,Object obj)使用指定元素obj替换指定List集合中的所有元素。static int frequence(Collection c,Object o)返回指定集合中指定元素的出现次数。static indexOfSubList(List source,List target)返回子List对象在父List对象中第一次出现的位置索引,如果父List中没有出现这样的子List,则返回-1。static int lastIndexOfubList(List source,List target)返回子List对象在父List对象中最后一次出现的位置索引,如果父List中没有出现这样的子List,则返回-1。static boolean replaceAll(List list,Object oldVal,Object newVal)使用一个新值newVal替换List对象的所有旧值oldVal。

同步控制: Collections提供了多个synchronizedXXX()方法, 该方法可以将指定集合包装成线程同步的集合, 从而解决多线程并发访问集合时的线程安全问题。 例如

Collections.synchronizedSet(new HashSet());

设置不可变集合:

方法描述emptyXXX()返回一个空的,不可变的集合对象,此处的集合既可以是List,也可以是Set,还可以是Map。singletonXxx()返回一个只包含指定对象(只有一个或一项元素)的,不可变的集合对象,此处的集合既可以是List,也可以是Set,还可以是Map。unmodifiableXXX()返回指定集合对象的不可变视图,此处的集合既可以是List,也可以是Set,还可以是Map。

上面三个方法可以生成出只读的Collection或Map。


总结

未完待续

杨明翰 认证博客专家 Java 技术讨论或联系作者请加QQ群:4794056,博客文章全部原创,所有文章不定期更新,系列文章会打成专栏,文章转载需先征求作者同意,版权必究。
最新回复(0)