java集合稳定性_Java集合

  • Post author:
  • Post category:java


一、hashCode与equals

这两个方法来自于Object类,所以每个类型都会自动继承这2个方法.这2个方法本质上并没有任何关系,彼此独立,而且这两个方法在脱离集合的环境下也是可以使用的.但这两个方法的理解对于更好的使用集合是必不可少的.

1.equals

Object类对equals的默认实现如下

public boolean equals(Object obj) {

return (this == obj);

}

这种实现只是表示引用相等,字符串对这个方法进行了重写,用于判断两个字符串的值是否相等.比如下面的代码

String s = new String(“abc”);

String s2 = new String(“abc”);

System.out.println(s==s2); //false

System.out.println(s.equals(s2));//true

通常重写 equals() 方法时,要重写 hashCode() 方法,以表示:如果两个对象是 equals 的,那么其 hashCode() 值也应该一样。

2.hashCode

hashCode方法主要用来支持java 集合框架中的Hash相关的集合,比如HashMap,HashSet等.

在Object类中hashCode的实现如下:

public native int hashCode();

这个是一个本地方法,其默认实现返回的hashCode是对象的内存地址进行hash算法得出的值.在hashCode的注释中,对hashCode的实现要求如下:

任何时候,反复调用同一个对象的hashCode方法,返回的值要一样

如果两个对象equals相等,那么其hashCode应该要一样

如果两个对象非equals相等,其hashCode可以一样,但不强制要求.

Hash 算法又叫散列算法,由 Hash(人名)首先提出。

Hash 算法:把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。

为什么要用 hash 算法?

Hash 算法的输出值是固定长度的,该值可以被用来作为内存地址。 这样取的时候,就可以通过计算其 hash 值来获取所在内存存储单元的地址,而快速的读取其存储的内容。

二、Comparable 与Comparator

jdk中的Comparable接口与Comparator接口都与排序有关,当对象放入到一些有序的集合时会对对象的排序性有要求,所以有必要了解这2个接口

1.Comparable

若一个类实现了Comparable接口,就意味着“该类支持排序” 此接口是jdk 1.2推出的,它的代码如下:

//java.lang jdk 1.2就有

public interface Comparable {

public int compareTo(T o);

}

当一个类实现了此接口时,通常是此实现类与compareTo方法传递过来的参数进行比较,比较的规则是当自身小于传递过来的对象时返回负数,相等就返回0,大于就返回正数.比如下面的代码:

class Student implements Comparable{

String name;

int age;

Student(String name,int age){

this.name=name;

this.age=age;

}

public int compareTo(Student st){

if(age==st.age)

return 0;

else if(age>st.age)

return 1;

else

return -1;

}

}

实现了Comparable接口后,此对象放入到集合中就可以对集合中的元素进行排序了,比如下面的代码

ArrayList al=new ArrayList();

al.add(new Student(“a”,23));

al.add(new Student(“b”,27));

al.add(new Student(“c”,21));

Collections.sort(al);

for(Student st:al){

System.out.println(st.name+” “+st.age);

}

输出结构为:

c 21

a 23

b 27

上面的结果可以看出以升序排序,如果想改为降序排序,必须修改Student类中的实现,把返回1的地方改为返回-1,返回-1的地方改为1.也就是说想改变排序规则必须修改源代码.还有一个不足之处就是只支持固定的排序规则,比如现在的实现只支持按年龄排序,不支持按名字排序.基于这种情况就需要使用Comparator来完成这样的功能.

2.Comparator

此接口在java.util包下,用来实现两个对象之间比较功能的.并且也并不要求被比较的对象实现某个接口.此接口的核心比较代码如下:

public interface Comparator {

int compare(T o1, T o2);

}

compare方法的比较逻辑与Comparable接口的compareTo方法类似,当第一个参数小于第二个参数时返回负数,相等返回0,大于返回正数.比如下面的代码实现了对Student类的年龄的比较

class AgeComparator implements Comparator{

public int compare(Student s1,Student s2){

if(s1.age==s2.age)

return 0;

else if(s1.age>s2.age)

return 1;

else

return -1;

}

}

下面的代码实现了对名字的比较

class NameComparator implements Comparator{

public int compare(Student s1,Student s2){

//String类本身实现了Comparable接口

return s1.name.compareTo(s2.name);

}

}

使用方式如下:

ArrayList al=new ArrayList();

al.add(new Student(“a”,23));

al.add(new Student(“b”,27));

al.add(new Student(“c”,21));

System.out.println(“依据名字进行比较”);

Collections.sort(al,new NameComparator());

for(Student st:al){

System.out.println(st.name+” “+st.age);

}

System.out.println(“依据年龄进行比较”);

Collections.sort(al,new AgeComparator());

for(Student st:al){

System.out.println(st.name+” “+st.age);

}

最终输出的结果为

依据名字进行比较

a 23

b 27

c 21

依据年龄进行比较

c 21

a 23

b 27

三、简介

数组主要存放的是同类型的数据,其最大的一个缺点就是其大小不能动态调整,这对于一些预先不确定数据量大小的情况无法应付,所以java推出了集合框架.

四、集合框架图

集合框架是存储于操纵一组对象的统一架构,它由一系列的接口和实现类组成,这些类型包含了如何存储对象以及操作这些数据的算法,比如排序算法.

整个java集合框架由Collection接口与Map接口代表.当然有一种说法认为java的集合框架只包含Collection接口体系,不包含Map接口代表的体系.下面是包含Collection与Map的整个架构:

1a4af40b5fe0149127afd9d8c21f61a5.png

下图是Collection接口代表的核心体系架构

4f3a93302f5f25e341d9fa8407b35103.png

五、List

List接口代表线性结构的集合,它以线性的方式来存储数据,并且允许存储重复的数据.此接口的主要实现类如下:

ArrayList

LinkedList

Vector

Stack

1.ArrayList

ArrayList是一个内部用数组实现List接口的集合类.

ArrayList list=new ArrayList();

list.add(“a”);

list.add(“b”);

在实例化集合对象时最好指定初始容量,容量大小尽量与预计存放的数据量差不多,值建议用2的n次方.这样可以减少集合频繁扩容造成的性能损失.如果不指定容量大小,ArrayList默认的大小为10.

ArrayList list=new ArrayList(4);

ArrayList由于内部是数组实现的集合,它支持通过索引来取得集合中的数据,比如

list.get(0)

通过索引取值的方式,其时间复杂度是个常量值.性能很高.但ArrayList集合删除数据或者往中间插入数据性能不高,因为其要逻动数据.

在遍历集合时,尽量不要进行集合的修改操作,比如删除元素.这非常容易产生bug,比如下面的代码:

List list = new ArrayList<>();

list.add(“1”);

list.add(“2”);

for (String item : list) {

if (“2”.equals(item)) { //把这里的2改为1试试

list.remove(item);

}

}

for (String item : list) {

System.out.println(item);

}

2.LinkedList

LinkedList用双链表来实现List接口,因而此类型往里面插入,删除速度性能较高.但通过索引取值的时间复杂度是O(n),性能不高.基本使用方法如下:

LinkedList al=new LinkedList();

al.add(“a”);

al.add(“b”);

六、Iterable与Iterator

实现了此接口的类型支持foreach循环,由于Collection接口的父类型就是Iterable,所以所有的Collection都支持foreach循环.

此接口的主要方法为Iterator iterator()此Iterator就是真正完成迭代功能的接口.Iterator接口的主要成员如下:

hasNext():检查迭代器是否还有元素

next():获取迭代器的下一个元素.

remove:删除一个元素.

迭代器(Iterator)中完成foreach循环的方法只有hasNext与next,remove主要用来完成在迭代的时候删除元素.

ArrayList list=new ArrayList();

list.add(“a”);

list.add(“b”);

Iterator it=list.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

在迭代集合的时候,如果要删除元素建议用迭代器实现.

七、Map

Map类型是一种键值对类型,键和值是一一映射(map)的,每一个键值对称之为一个条目(Entry).Map包含唯一的键.Map集合非常适合依据键来搜索,更新,删除元素的情况.map的体系结构如下:

6d5092e422ec86594c937e3ff3c9e26b.png

从上图中看出Map的类型主要有以下几个:

HashMap:它不维护插入元素的顺序(order)

LinkedHashMap:它维护插入的顺序

TreeMap:它支持排序.默认是升序排列Map中的元素.

Map不允许有重复的键,但值允许重复.HashMap与LinkedHashMap允许键与值存放null值,但TreeMap的键与值都不允许null值.

1.HashMap

HashMap 首先初始化一块内存(数组)。把内存划分为一个一个的存储空间(bucket),每一个存储空间都有一个地址与其对应。但是,一个存储空间,不限于只存一对键值对(HashMap 使用 LinkedList 存储多个具有相同 hashCode 的键值对。新加的放在最前).基本使用如下:

Map map=new HashMap();

map.put(1,”a”);

map.put(5,”b”);

map.put(2,”b”);

map.get(1) //去值,结果为:a

2.存值

存放值的时候会依据键的hasCode值来确定存放的槽位(backet),如果此槽位没内容,直接存放.如果此槽位有内容就比较槽位已有对象与即将插入对象的相等性(equals方式比较),相等的话就覆盖,不相等就直接插入此槽位的linkedList里面去.

3.取值

使用一个object作为键来取HashMap 中对应的值时,HashMap 的工作方法是:通过传入的键的 hashcode() 在Map中找槽位,当找到这个槽位后再通过 equals() 来比较传入的object和地址中的object(s)(可能是多个),结果为 true 就取出 value。

4.遍历

HashMap可以分别对其键,值,键值对进行遍历,效率最高的遍历方式是键值对的遍历方式.因为只遍历键来取值的话其实是把集合遍历了2次

//键的遍历

for(Integer k: map.keySet()) {

System.out.println(k);

}

//值的遍历

for(String v:map.values()) {

System.out.println(v);

}

// 键值对遍历

for(Map.Entry entry: map.entrySet()) {

System.out.println(“key:” + entry.getKey() + ” value: ” + entry.getValue());

}

5.对象作为key

假设有这么一个类想作为Map集合中的键,在存放到集合中的时候需要注意处理其hashCode与equals方法的重写问题.

public class Person {

private int id;

public Person(int id) {

this.id = id;

}}

使用的代码如下,最终集合中的数量为2.因为p1与p2是两个不同的对象.

Map map = new HashMap<>(4);

Person p1 = new Person(1);

Person p2 = new Person(1);

map.put(p1, “a”);

map.put(p2,”b”);

System.out.println(map.size());//输出的结果是2

如果你基于业务的需要觉得两个Person对象的id是一样的话,应该是相等的,那么你此时就应该重写equals方法.按照规范,重写equals方法时应该也相应的重写hashCode方法.利用eclipse帮我们生成的equals与hashCode方法实现,最终person类的代码如下:

public class Person {

private int id;

public Person(int id) {

this.id = id;

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + id;

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Person other = (Person) obj;

if (id != other.id)

return false;

return true;

}

}

再次运行上面的代码会发现最终集合中的数量是1.

八、TreeMap

内部用树结构实现的一个有序的Map类型.其排序是依据键来进行排序的,并且要求所有的键实现了Comparable接口

Map map=new TreeMap();

map.put(1,”a”);

map.put(5,”b”);

map.put(2,”b”);

for(Map.Entry entry: map.entrySet()) {

System.out.println(“key:” + entry.getKey() + ” value: ” + entry.getValue());

}

输出的结果为:

key:1 value: a

key:2 value: b

key:5 value: b

如果存放的键的类型没有实现Comparable接口会报ClassCastException.键的类型必须实现了Comparable接口.代码如下:

public class Person implements Comparable {

private int id;

public Person(int id) {

this.id = id;

}

public int getId() {

return this.id;

}

// 省略hashCod与equals方法的实现,与上面的一样.

@Override

public int compareTo(Person p) {

if(this.id < p.getId()) {

return -1;

}else if(this.id == p.getId()) {

return 0;

}else {

return 1;

}

}

}

使用此类的代码如下,最终输出的结果为1,3,10的升序排列

Map map = new TreeMap<>();

Person p1 = new Person(10);

Person p2 = new Person(1);

Person p3 = new Person(3);

map.put(p1, “a”);

map.put(p2,”b”);

map.put(p3,”c”);

for(Map.Entry entry:map.entrySet()) {

System.out.println(entry.getKey().getId());

}

九、Set

它主要用来存放不重复的数据,可以存放null值,但只能存放一个null值.set集合是无序的,主要实现类有HashSet,LinkedHashSet,TreeSet.可以利用Set元素唯一的特性快速对一个集合进行去重的操作.

1.HashSet

内部用一个hash map集合来存放数据,存放数据时利用对象的hashcode来确定是否存在重复.基本使用如下:

HashSet set=new HashSet();

set.add(“a”);

set.add(“b”);

set.add(“b”);  // 总数量为2

2.TreeSet

此集合是有序的.基本使用方法如下:

HashSet set=new TreeSet();

set.add(“a”);

set.add(“b”);

set.add(“c”); // 总数量为2

十、Stack

栈是一种先进后出的数据结构,java集合中用Stack类实现栈这种数据结构,此类是Vector的子类,并添加了push,pop,peek等栈专有的方法.其基本使用方法如下:

Stack stack = new Stack();

stack.push(“a”);

stack.push(“b”);

stack.pop();

十一、Queue

队列是一种先进先出的数据结构,在集合框架中用Queue接口代表队列.常见的实现类有:

LinkedList

PriorityQueue

ArrayDeque()

LinkedList

LinkedList ll = new LinkedList<>();

ll.addFirst(“a”);

ll.addFirst(“b”);

String value = ll.removeLast();// value为a

十二、总结

4f36940fb8f9228e1ad45a4bf4e21caf.png

6a66e6962aef0d29486b92a06fffffcb.png

27e3bdb7eb2dc2ac87b4f09607b539cc.png

35f2a6d4381866a146f2e3262f59eafb.png

十三、Collections

此类是java.util包下的一个工具类,不能实例化,此类包含的都是一些静态的方法,用来操作集合或者返回集合.此类包含的方法主要有以下一些作用

排序

搜索

往集合填充,拷贝数据

求取集合的最大值最小值

获取集合的只读视图

获取线程安全的同步集合

获取空的集合

获取检查集合

下面的代码演示了Collections类的一些常见用法

ArrayList list = new ArrayList();

list.add(4);

list.add(3);

list.add(1);

list.add(2);

list.add(3);

// 排序

Collections.sort(list);

// 二分查找的前提是排序好的元素

System.out.println( Collections.binarySearch( list , 8 ) );  // 找不到返回-1

// 反序集合输出

Collections.reverse( list );

System.out.println( list );

// 求最大值

System.out.println( Collections.max( list ) );   // 4

//   使用指定的元素替换指定集合中的所有元素

Collections.fill( list, 5 );

System.out.println( list );

十四、Arrays

此类是java.util包下的一个工具类,不能实例化,主要包含一些操作数组或者返回数据的工具方法.此类的方法主要有如下功能

排序

二分搜索

填充

拷贝

转换为流

字符串显示数组

转换为集合视图

下面的代码是一些常见的操作

// 将数组转换为集合视图

ArrayList list = new ArrayList();

Integer is[] = new  Integer[]{6,7,8};

List list2 =  Arrays.asList(is);

list.addAll( list2 );

System.out.println( list );

// 将List转换为数组

Object [] ins =  list.toArray();

System.out.println( Arrays.toString( ins ) );

十五、有序性与稳定性

在阿里巴巴的编码规范中有这么一句话:合理利用集合的稳定性(order)和有序性(sort),避免集合的无序性和不稳定性带来的负面影响。稳定性指集合每次遍历的元素次序是一定的。有序性是指遍历的结果按某种比较规则依次排序的。

如ArrayList是order/unsort,HashMap是unorder/unsort,TreeSet是order/sort

比如下面的代码演示了HashMap的不稳定:

Map map = new HashMap<>();

map.put(1,11);

map.put(2,22);

for(Map.Entry entry:map.entrySet()) {

System.out.println(entry.getKey());

}

System.out.println(“——“);

map.put(17,17);

for(Map.Entry entry:map.entrySet()) {

System.out.println(entry.getKey());

}

输出的结果是:由于新插入一个值导致两次遍历的结果是不一样的.这就是不稳定性

1

2

——

1

17

2

十六、null的处理

集合类KeyValue父类说明

Hashtable

不允许null

不允许null

Dictionary

线程安全

ConcurrentHashMap

不允许null

不允许null

AbstractMap

锁分段

TreeMap

不允许null

允许

AbstractMap

线程不安全

HashMap

允许

允许

AbstractMap

线程不安全

十七、异同点

1.ArrayList和LinkedList

(1)ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

(2)对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针。

(3)对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

2.HashTable与HashMap

相同点:

(1)都实现了Map、Cloneable、java.io.Serializable接口。

(2)都是存储”键值对(key-value)”的散列表,而且都是采用拉链法实现的。

不同点:

(1)历史原因:HashTable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 。

(2)同步性:HashTable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 。

(3)对null值的处理:HashMap的key、value都可为null,HashTable的key、value都不可为null 。

(4)基类不同:HashMap继承于AbstractMap,而Hashtable继承于Dictionary。

Dictionary是一个抽象类,它直接继承于Object类,没有实现任何接口。Dictionary类是JDK 1.0的引入的。虽然Dictionary也支持“添加key-value键值对”、“获取value”、“获取大小”等基本操作,但它的API函数比Map少;而且Dictionary一般是通过Enumeration(枚举类)去遍历,Map则是通过Iterator(迭代M器)去遍历。 然而由于Hashtable也实现了Map接口,所以,它即支持Enumeration遍历,也支持Iterator遍历。

AbstractMap是一个抽象类,它实现了Map接口的绝大部分API函数;为Map的具体实现类提供了极大的便利。它是JDK 1.2新增的类。

(5)支持的遍历种类不同:HashMap只支持Iterator(迭代器)遍历。而Hashtable支持Iterator(迭代器)和Enumeration(枚举器)两种方式遍历。

3.HashMap、Hashtable、LinkedHashMap和TreeMap比较

Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。

Hashtable 与 HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。对于LinkedHashMap而言,它继承与HashMap、底层使用哈希表与双向链表来保存所有元素。其基本操作与父类HashMap相似,它通过重写父类相关的方法,来实现自己的链接列表特性。

TreeMap实现SortMap接口,内部实现是红黑树。能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。

使用场景

一般情况下,我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。

TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。

LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。

4.HashSet、LinkedHashSet、TreeSet比较

Set接口

Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。

Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象。

HashSet

HashSet有以下特点:

->  不能保证元素的排列顺序,顺序有可能发生变化。

->  不是同步的。

->  集合元素可以是null,但只能放入一个null。

当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。

注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

LinkedHashSet

LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

TreeSet类

TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。

TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0。

5、Iterator和ListIterator区别

我们在使用List,Set的时候,为了实现对其数据的遍历,我们经常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。但是在使用的时候也是有不同的。List和Set都有iterator()来取得其迭代器。对List来说,你也可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:

(1)ListIterator有add()方法,可以向List中添加对象,而Iterator不能

(2)ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

(3)ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

(4)都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。

因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。

6、Collection 和 Collections区别

(1)java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。

(2)java.util.Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架。



版权声明:本文为weixin_42458217原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。