文章目录

  • 传送门
  • 前言
  • 什么是集合框架
  • 集合框架体系
    • Collection接口
      • `Set接口`
        • `HashSet`
          • LinkedHashSet
        • TreeSet
        • EnumSet
      • Queue接口
        • PriorityQueue
        • Deque接口
      • `List接口`
        • `ArrayList`
        • LinkedList
        • Vector
    • `Map接口`
      • `HashMap`
        • `LinkedHashMap`
      • Hashtable
      • TreeMap
      • WeakHashMap
      • IdentityHashMap
      • EnumMap
  • Collections
  • 总结

传送门

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

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

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

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

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

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

  7. 杨明翰的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开始),否则返回-1System.out.println("index==>" + list1.indexOf(2));// 如果list中有此元素则返回最后一次出现的该元素的下标(从0开始),否则返回-1System.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添加另外一个listList<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);// 清空listlist1.clear();System.out.println(list1);// list的四种遍历方式List<String> list4 = new ArrayList<String>();list4.add("A");list4.add("B");list4.add("C");// 第1种使用foreach遍历Listfor (String str : list4) { //System.out.println(str);}// 第2种使用原始forfor (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的Lambdalist4.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);}// 第五种JDK8map.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教学系列之集合框架篇V0.2(持续更新)相关推荐

  1. 明翰Java教学系列之进阶面向对象篇

    复习 1.Java有多少种数据类型,数据类型的分类?数据类型的大小排序?默认类型?默认值? 2.Java的工作机制? 3.Java中有多少种初始化数组的方式? 4.什么是变量,如何定义变量?Java中 ...

  2. 明翰Java教学系列之认识Java篇V1.3(持续更新)

    文章目录 传送门 前言 什么是Java? Java之父 `Java的应用场景` Java部分特点 Java工作机制 JDK(Java Development Kit) JRE(Java Runtime ...

  3. 明翰Java教学系列之多线程篇V0.2(持续更新)

    文章目录 传送门 前言 背景知识 并行与并发 线程与进程 内存模型 1. 计算机内存模型 `2. Java内存模型` 2.1 内存交互 2.1.1 交互操作 2.1.2 交互规则 `2.2 并发编程特 ...

  4. 明翰英语教学系列之冠词篇

    文章目录 前言 定冠词 定冠词的用法 1. `定冠词的特指用法` 1.1 `某个或者某些特定的人或物` 1.2 `上文提过的人或物(第二次提到)` 1.3 双方彼此都知道的人或物(默认) 1.4 形容 ...

  5. 明翰英语教学系列之方法篇

    文章目录 传送门 前言 `学习路径&知识体系` 学习技巧 `构词规律` `词汇的偏旁部首` 词义前缀 否定前缀 `in-` mis- dis- de- un- con前缀 out前缀 sur前 ...

  6. 明翰英语教学系列之雅思阅读篇V0.9(持续更新)

    文章目录 传送门 6. 阅读 READING 6.1 阅读评分标准 6.2 阅读题型 `6.2.1 阅读填空题` `摘要填空题(Summary)` `无选项摘要填空` 1. 找定位词 2. 确定答案词 ...

  7. 明翰英语教学系列之动词篇V0.3

    文章目录 传送门 前言 1. 动词概念 2. `动词的分类` 2.1 按照功能分类 2.1.1 实义动词&行为动词 2.1.2 `系动词&联系动词` 系动词的分类 `状态系动词` `感 ...

  8. 明翰英语教学系列之数词篇V0.2(持续更新)

    文章目录 传送门 什么是数词 基数词 基数词的单复数 序数词 数词应用 `表达[日期/时间]` 日期 年 月.日 年.月.日 `时间` 直接表达 间接表达 分数 小数 百分数 钱币 长度单位 重量单位 ...

  9. 明翰全日制英国硕士留学攻略V2.7(持续更新)

    文章目录 传送门 前言 1. 留学准备 1.1 `留学原因` 1.2 选择国家 1.3 `选择中介` 1.4 `选择学校与专业` `offer` 1.4.1 预科 1.4.2 `1年制与2年制` 1. ...

最新文章

  1. 用Python分析了1w场吃鸡数据,原来吃鸡要这么玩!
  2. RH系列linux上编译android2.3(gingerbread)
  3. C++编程进阶2(编译器在类内默认生成的函数讨论以及纯虚析构函数)
  4. Sublime和Webstorm新建代码块
  5. js实现旋转木马轮播图
  6. java8 streams_另一个Java 8 Lamdbas和Streams示例
  7. 第76节:Java中的基础知识
  8. TelPhoneManager中的常用方法和状态获取
  9. 咦?Storyboard在WPF变换中怎么不能用了?
  10. Python_基于statsmodel包画Bland altman plot (Mean Difference Plot)用于预测结果分析
  11. Python Bug: TypeError: a bytes-like object is required, not ‘str
  12. 全网首发:怎样制作CDKEY(6)-CDKEY破解
  13. dsoframer.ocx java_dsoframer.ocx(java web 操作word) 总结一下
  14. 高等数学660---从214到221
  15. 写给大家看的量子力学——量子通信、量子隐形传输技术简介
  16. nodejs Log4js v2.x配置使用
  17. Bugzilla使用
  18. 腾讯云服务器怎么搭建多个ip,(技巧)利用腾讯云架设多ip实现单窗口单ip
  19. 前端基础(二):HTML之列表、表格、表单标签
  20. IOS手机安装旧版APP(不要问我为什么安装旧版,有的旧版功能更强大)

热门文章

  1. oce专项认证 oracle_今年取得的Oracle方面的认证证书总结
  2. 我见过的,最易上手的Shader入门教程(图文)
  3. Solidity 构造函数的理解
  4. 升学——妹妹小鱼儿升学所让我想到的
  5. 《OpenGL超级宝典(第5版)》——第1章,第1.1节计算机图形的简单历史回顾
  6. react实现tree组件
  7. 二,八,十六进制c语言,数制 二·八·十六进制 C语言
  8. 厦门故事(一):人生有无数个夏天,却只有一次少年
  9. 大型网站架构之大型网站核心架构要素
  10. 《那些年啊,那些事——一个程序员的奋斗史》——34