一、概述
Java是面向对象的语言,我们在编程的时候自然需要存储对象的容器,数组可以满足这个需求,但是数组初始化时长度是固定的,但是我们往往需要一个长度可变化的容器,因此,集合出现了。
Java集合主要由两个接口而派生出:Collection、Map;
斜体的为接口,正体的为实现类;
二、集合与数组的区别
(1)长度区别:集合长度可变,数组长度不可变
(2)内容区别:集合可存储不同类型元素,数组存储只可单一类型元素
(3)元素区别:集合只能存储引用类型元素,数组可存储引用类型,也可存储基本类型
三、Collection接口
构造:Collection co=new 子类构造;
成员方法:
boolean add(Object o)
:添加一个元素;
boolean addAll(Collection c)
:将一个集合加入;
void clear( )
:清除集合所有元素;
boolean isEmpty()
:判断集合是否为空;
Iterator iterator()
:返回该集合的迭代器对象;
boolean remove(Object o)
:删除集合里第一个o元素;
boolean removeAll(Collection c)
:删除集合里所有c中所包含的元素;
int size()
:返回集合元素的个数;
boolean retainAll(Collection c)
:删除集合c中没有的元素;
Object[] toArray()
:集合转化为数组;
boolean contains(Object o)
:是否包含元素o;
boolean containsAll(Collection c)
:是否包含c里面所有的元素;
Iterator迭代器
作用:遍历集合
通过集合调用Iterator()方法产生:
Set<String> hashset=new HashSet<>();
Iterator<String> it=hashset.iterator();
成员方法:
boolean hasNext()
:判断是否有下一个元素;
Object next()
:返回集合下一个元素;
void remove()
:删除集合里上一次next返回的元素;
class test{
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("a");
c.add("b");
c.add("c");
c.add("d");
Iterator<String> it = c.iterator();//此处设置泛型String,下面it.next()就不需要强转
while (it.hasNext()) {
String s = it.next();
if (s.equals("b")) {
it.remove();/使用c.remove(s)报错
}}}}
当遍历集合时需要删除元素必须要使用迭代器里的remove()方法,而不能用集合的remove()方法,否则会抛异常。
原因是:
集合调用iterator()方法返回Iterator对象时,把容器中包含元素的个数赋值给了一个变量expectedModCount,调用next()方法时会比较该变量值与实际元素个数是否相等,若不相等就会抛异常。所有在遍历时,使用集合的remove()、add()方法都会使集合元素个数发生变化,导致异常;
遍历Collection下面的集合不仅可以用迭代器,使用for循环也可以;
for (String s : c) {
System.out.println(s);
}
四、List接口
List接口继承自Collection接口,拥有Collection接口的大部分方法;
特点:List 有序,元素可重复,有索引;
它利用索引(index),定义了一些特殊方法:
Object get(int index)
:获取指定位置的元素;
Object remove(int index)
:移除并返回指定位置的元素;
void add(int index,E e)
:将元素添加到指定位置;
Object set(int index,E e)
:用元素替换指定位置的元素,并返回原来的值;
int indexOf(E e)
:返回第一次e出现的索引;
List subList(int i,int b)
:返回集合【a,b);
void sort(Comparator c)
:根据接口规则排序;
特有的迭代器
ListIterator listIterator()
:获取ListIterator 迭代器;
ListIterator 接口继承自Iterator接口,专门操作List集合,相比普通的迭代器,该迭代器可以向前(反向)迭代,可以向集合中添加元素,具体方法为:
boolean hasPrevious()
:是否还有上一个元素;
Object previous()
:返回上一个元素;
void add(Object o)
:在迭代处插入元素;
【反向迭代之前需要先正向迭代一遍】
Ⅰ、派生类及其特点
①ArrayList
优点: 查询快(因为是连续的内存空间,方便寻址),效率高。
缺点: 增删慢(因为需要发生数据迁移),线程不安全。
底层数据结构:数组。
最常用,没有额外方法,均使用List提供的方法;
如何扩容:
创建一个新数组,长度为用来长度的1.5倍,将原数组数据迁移到新数组;
ArrayList拥有一个初始化的容量大小initialCapability,默认为10,当元素个数大于该值时集合长度会自动增长为原来的1.5倍;
②Vector
优点: 查询快,线程安全。
缺点: 增删慢,效率比ArrayList低。
底层数据结构:数组。
Vector拥有一个初始化的容量大小initialCapability,默认为10,当元素个数大于该值时集合长度会自动增长为原来的2倍;
特有方法:
public void addElement(E e)
:添加元素,相当于add(E e);
public E elementAt(int index)
:获取索引i处的元素,相当于get(int i);
public Enumeration<E> elements()
:类似于获取集合的迭代器,相当于iterator();
class test2{
public static void main(String[] args) {
Vector<String> v=new Vector<>();
v.add("a");
v.add("b");
v.addElement("c");
v.addElement("d");
System.out.println(0+" "+v.elementAt(0));
System.out.println(0+" "+v.get(0));
Enumeration<String> elements = v.elements();
while (elements.hasMoreElements()) {
String s = elements.nextElement();
System.out.println(s);
}
Iterator<String> it = v.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}}}
③LinkedList
优点: 增删快(只需要改变前后节点的指针指向),效率高。
缺点: 查询慢(需要通过指针一个个寻找),线程不安全。
底层数据结构:双向链表。
特有方法:
添加:
addFirst(E e)
:添加元素到开头;
addLast(E e)
:添加元素到末尾;
删除;
Object removeFirst()
:删除开头的元素,并返回;
Object removeLast()
:删除末尾的元素,并返回;
获取:
Object getFirst()
:获取开头元素;
Object getLast()
:获取末尾元素;
class test3{
public static void main(String[] args) {
LinkedList<String> linkedList=new LinkedList<>();
linkedList.add("1");
linkedList.add("2");
linkedList.add("3");
linkedList.addFirst("0");
linkedList.addLast("4");
Iterator<String> iterator = linkedList.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
System.out.print(next);
}//01234
linkedList.removeFirst();//0
linkedList.removeLast();//4
System.out.print(linkedList.getFirst());//1
System.out.println(linkedList.getLast());//3
}
}
选择与使用:
若对数据主要操作为随机访问,或只是在集合末端添加、删除元素时,使用ArrayList效率较高;
若对数据主要操作为在指定位置插入、删除元素时,使用LinkedList效率较高;
若在多线程中使用集合时,使用Vector较为安全;
五、Set接口
Set接口继承自Collection接口,拥有Collection接口的大部分方法;
特点:Set无序,元素不可重复;
Ⅰ、派生类及其特点
①HashSet
1.1、特点:
- 无序,不能保证顺序与添加时相同
- 元素不允许重复,可以为null
- 线程不安全,效率高
- 底层数据结构:哈希表(数组+单向链表)
注意点:
【尽量不要修改集合中的元素的值,因为修改了的话,它们的equals()、hashCode()方法的返回值可能会变化,导致无法正确的操作这些集合】
1.2、重写hashCode()和equals()
HashSet集合元素的唯一性是靠所存储元素类型是否**重写hashCode()和equals()**方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
具体实现唯一性的比较过程:
存储元素首先会使用hashCode()算法函数生成一个int类型hash散列值,然后已经的所存储的元素的hashCode值比较;
如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;
如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处类似一个新的链表,在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。
重写:
class Student {
String name;
int id;
@Override
public boolean equals(Object o) {
if (o instanceof Student) {
Student student = (Student) o;
if (student.name.equals(this.name) && student.id == this.id) {
return true;
}
return false;
} else {
return false;
}
}
@Override
public int hashCode() {
return name.hashCode();
}
}
1.3、重写的约定:
两个对象的equals()方法返回值为true,则它们调用hashCode()值也要相同;
若它们调用的hashCode()返回的值不相同,它们调用equals()方法返回false;
当hashCode()返回值相同时,这两个对象不一定相同;
equals()方法返回值为true时才认为这两个对象相同;
1.4、实际上只需要equals()方法就能判断元素是否有重复,那为什么还要重写hashCode呢?
如果直接用equals()去比较的话,如果存在1000元素,你new一个新的元素出来,就需要去调用1000次equals()去逐个比较他们是否相同,这样会大大降低效率。
hashCode()实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,
如果这个位置上已经存在元素,这个时候才去调equals()方法与新元素进行比较;
1.5、Hash表(哈希表)
定义:Hash表是根据关键码值而直接进行访问的一种数据结构。
它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度,这个映射函数叫做散列函数,存放记录的数组叫做散列表。
HashSet初始化容量为16。
数据结构:
JDK1.8之前:哈希表(数组+单向链表);
JDK1.8之后:哈希表(数组+单向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树,其目的是当数据量大时,减少查找的时间;
②LinkedHashSet
作为HashSet的子类,只是比它多了一条链表,这条链表用来记录元素顺序,因此LinkedHashSet其中的元素有序。
特点:
- 底层数据结构:双向链表+哈希表
- 链表保证了元素的顺序与存储顺序一致(有序)
- 哈希表保证了元素的唯一性(不可重复)
- 元素可以为null
- 线程不安全,效率高
③TreeSet
TreeSet实现了继承于Set接口的SortedSet接口 ,它支持两种排序方法,自然排序和比较器排序
1.1特点
- 元素有序(按一定规则排序,并不是像LinkedHashSet一样和插入时顺序一样)
- 元素不允许重复
- 元素不能为null
- 查询快,增删慢
- 线程不安全,效率低
- 底层数据结构:红黑树
注意点:
①【对于TreeSet集合而言,判断两个对象相等的标准是compareTo()的返回值为0,compare()方法也可】
②【与HashCode()一样,尽量不要修改集合中元素的值】
1.2特有方法:
Object first()
:返回第一个元素
Object last()
:返回最后一个元素
Object lower(Object o)
:返回集合中小于指定元素的最大元素
Object higher(Object o)
:返回集合中大于指定元素的最小元素
SorterSet subSet(Object a,Object b)
:返回集合【a,b);
SorterSet headSet(Object a)
:返回集合【0,a);
SorterSet tailSet(Object a)
:返回集合【a,last】;
class test7{
public static void main(String[] args) {
TreeSet<Student> treeSet=new TreeSet<>();
treeSet.add(new Student("abc",1));
treeSet.add(new Student("ab",1));
treeSet.add(new Student("c",1));
treeSet.add(new Student("ac",1));
treeSet.add(new Student("ac",0));
SortedSet<Student> students = treeSet.subSet(new Student("abc", 1), new Student("ac", 1));
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()) {
Student next = iterator.next();
System.out.println(next);
}
}
}
1.3自然排序
我们自定义类自然排序时要进行以下操作:
- 实现 Comparable接口,并重写接口中的Compareto()方法
如:
class Student implements Comparable<Student>{/实现Comparable接口
String name;
Integer id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
@Override/重写compareTo()
public int compareTo(Student o) {
int result1= this.name.compareTo(o.name);//升序排序则this在前
/因为String类内部已经实现了compareTo()方法,所以可以直接用
if(result1==0){
return this.id.compareTo(o.id);/对比了name属性,再对比id
}else {
return result1;
}}}
【就像hashCode()与equals()方法一样,包装类与String类都有重写compareTo()方法】
compareTo(T b)方法
那Integer为例:
a.compareTo(b)
return (a < b) ? -1 : ((a == b) ? 0 : 1);
首先其返回值为int类型:
- 当返回值小于0时,表示a小于b;
- 当返回值等于0时,表示a等于b;
- 当返回值大于0时,表示a大于b;
【a为方法调用者,b为方法参数】
升序排序,a在前,否则b在前;
1.4比较器排序
在构造器里添加一个Comparator接口:
TreeSet tree=new TreeSet(Comparator<? superE> comparator)
实现比较器排序要实现以下操作:
- 单独创建一个类继承Comparator接口,并实现接口里的Compare()方法;
- 在TreeSet集合构造器内传入该类的一个实例(一般用匿名内部类);
自定义类:
class person{
int num;
String name;
person(int num,String name){
this.name=name;
this.num=num;
}
}
测试:
class ComparatorTest{
public static void main(String[] args) {
TreeSet<person> tree = new TreeSet<>(new Comparator<person>() {//匿名内部类实现Comparator接口
@Override
public int compare(person o1, person o2) {
System.out.println("c");
int result1=Integer.compare(o1.num,o2.num);//Integer有compare方法(静态),可以直接用
//int result1=o1.num-o2.num; //也可以自己写,达到同样效果
if(result1==0){
return o1.name.compareTo(o2.name);//String类没有compare方法,所以使用其compareTo()方法
}else {
return result1;
}
}
});
tree.add(new person(1,"a"));
tree.add(new person(1,"a"));
tree.add(new person(1,"c"));
tree.add(new person(3,"b"));
tree.add(new person(2,"c"));
Iterator<person> iterator = tree.iterator();
while (iterator.hasNext()) {
person next = iterator.next();
System.out.println(next);
}}}
compare(T a,T b)方法
比较两个排序的对象,与compareTo()方法一样
其返回值为int类型:
- 当返回值小于0时,表示a小于b;
- 当返回值等于0时,表示a等于b;
- 当返回值大于0时,表示a大于b;
【a为方法调用者,b为方法参数】
升序排序,a在前,否则b在前;
【包装类都有重写compare()方法,String没有】
set集合特点及比较:
顺序:
- HashSet只是通用的存储数据的集合(无序)
- LinkedHashSet的主要功能用于保证FIFO即有序的集合(先进先出)
- TreeSet的主要功能用于排序
线程安全:
- 三者都是线程不安全的
插入效率:
- HashSet插入数据最快,其次LinkHashSet,最慢的是TreeSet因为内部实现排序
是否允许null元素:
- HashSet和LinkHashSet允许存在null数据,但是TreeSet中插入null数据时会报错(空指针异常)
六、Queue接口(用地比较少)
Queue接口继承自Collection接口,拥有Collection接口的大部分方法;
特点:
- Queue模拟队列”先进先出“;
- 添加元素只能在队尾,移除只能在队首。
常用方法:
添加
boolean offer(Object o)
:添加元素到队尾,,插入成功返回 true;否则返回 false。
void add(Object o)
:添加元素到队尾,若失败(可能容量不够)则抛出IllegalStateException异常(offer方法通常要优于 add方法)
获取
Object peek()
:获取队头元素,如果此队列为空,则返回 null
Object element()
:获取队头元素,如果此队列为空,则将抛出NoSuchElementException异常
删除
Object poll()
:获取队头元素并删除,如果此队列为空,则返回 null
Object remove()
:获取队头元素并删除,如果此队列为空,则抛出NoSuchElementException异常
其他
boolean isEmpty()
:判断一个队列中是否为空。
Ⅰ、其派生
①PriorityQueue类
PriorityQueue 类实质上维护了一个有序列表,它支持两种排序方法,自然排序和比较器排序;
特点:
- 元素有序(排序与TreeSet一致)
- 元素可以重复,不允许null
- 线程不安全
- 无边界,非阻塞
class PriorityQueueTest{
public static void main(String[] args) {
PriorityQueue<Integer> queue=new PriorityQueue<>();
queue.offer(1);
queue.offer(3);
queue.offer(2);
Iterator<Integer> iterator = queue.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());/1,2,3
}}}
②Deque接口
Deque接口是Queue接口的子接口,是一个“双端队列
”,也可以当作“栈
”使用。
特点:
- 双端队列,允许两端都可以进行入队和出队操作的队列。
- 元素有序,允许重复
- 线程不安全
- 底层数据结构:双向链表
方法:
其中
蓝色的为添加元素的方法
红色的为删除相关的方法(部分是删除并返回)
绿色的为获取元素的方法(不会删除)
紫色的为其他常用方法
栈方法:
Object pop()
:取出栈顶元素,相当于removeFirst();
void push(Object o)
:将元素加入到栈顶,相当于addFirst(Object o);
③LinkedList类
LinkedList既实现了List接口,也实现了Deque接口,所以LinkedList也是Queue的一个实现类。
(内容见List接口派生)
优点: 增删快(只需要改变前后节点的指针指向),效率高。
缺点: 查询慢(需要通过指针一个个寻找),线程不安全。
底层数据结构:双向链表。
④ArrayDeque类
查找快,增删慢。
底层为Object数组。
七、Map接口
Map接口是双列集合,元素包含两个值(key,value)即键值对, key不允许重复,value可以重复, key与value是一一对应的。
特点:元素无序,key不可重复;
Map<key,value> map=new 子类构造<>();
方法:
Object put(key,value)
:添加一个键值对,如果存在该key,则覆盖原来的value
Object get(key)
:通过key获取value,没有则返回null
Object remove(key)
:删除key所对应的键值对,并返回其value,没有就返回null
Object replace(key,value)
:替代key对应的value
Set keySet()
:返回该map中所有key组成的set集合
Collection values()
:返回该map中所有value所组成的Collection集合
boolean containsKey(key)
:判断集合中是否含有该key
boolean containsValue(value)
:判断集合中是否含有该value
boolean isEmpty()
:判断集合是否为空
void clear()
:清除集合所有键值对
int size()
:返回集合元素个数
void putAll(Map map)
:将map添加到集合中
Set entrySet()
:返回map集合中所有键值对组成的Set集合,每个集合元素都是Map.Entry对象(Map的内部类)
内部类Entry方法:
Object getKey()
:获取该Entry的key值
Object getValue()
:获取该Entry的value值
Object setValue(value)
:设置该Entry的value值
class MapTest1{
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
map.put(1,"apple");
map.put(4,"date");
map.put(2,"bili");
map.put(3,"cup");
System.out.println(map.get(4));
System.out.println(map.replace(1, "abs"));
System.out.println(map.containsKey(1));
System.out.println(map.containsValue("apple"));
System.out.println(map.remove(4));
System.out.println(map.size());
System.out.println(map.remove(4, "apple"));
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
Map没有迭代器,遍历集合可以用以下方法:
- keySet() —> 遍历 —> get(key)
- entrySet() —> 遍历 —> entry.getKey()+entry.getValue()
class MapTest2{
public static void main(String[] args) {
Map<Integer, String> hashMap= new HashMap<>();
hashMap.put(10, "a");
hashMap.put(5, "c");
hashMap.put(18, "b");
//两种遍历方式
//1. 使用keySet()方法获取key组成的set集合
// 再遍历set集合(for循环、set迭代器)
// 直接输出key,调用get(key)方法获取value值
for (int key : hashMap.keySet()) {
System.out.println(key + " " + hashMap.get(key));
}
//2. 通过entrySet()方法获取Map的内部类Entry的一个Set集合
// 再遍历该set集合(for循环、set迭代器)
// 调用Entry的getKey()获取key值,getValue()获取value值
Iterator iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = (Map.Entry<Integer, String>) iterator.next();
System.out.println(entry.getKey() + " " + entry.getValue());
}
}}
Ⅰ、派生类及其特点
①HashMap
HashMap可以看作:HashSet组成的key,value是任意引用类型;
特点:
- key唯一,key对象必须重写hashCode()与equals()
- key可以为null
- 无序
- 线程不安全
- key底层数据结构:哈希表
②LinkedHashMap
继承HashMap,在此基础上添加了双向链表维护key顺序,类似HashSet与LinkedHashSet的关系。
特点:
- key唯一,key对象必须重写hashCode()与equals()
- key可以为null
- 有序(与添加顺序一致)
- 线程不安全
- key底层数据结构:哈希表+双向链表
③Hashtable
特点:
- key唯一,key对象必须重写hashCode()与equals()
- 线程安全,效率低
- 不可以存入null键,null值。
- 底层数据结构:哈希表
【Hashtable最大特点就是,线程安全,若不考虑线程安全时,一般不用这个,通常用hashMap】
④Properties
Properties文件是java中很常用的一种配置文件,文件后缀为“.properties”,属文本文件,文件的内容格式是“键=值”的格式,可以用“#”作为注释,运用配置文件,可以便于java深层次的解耦。如使用JDBC连接数据库时,通常将数据库连接配置代码写到配置文件中。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user
user=root
password=123456
java中提供了配置文件的操作类Properties类(java.util.Properties),Properties类继承了Hashtable
常用方法:
setProperty(String key, String value)
:添加键值对
getProperty(String key)
:获取指定键对应的值
getProperty(String key, String defaultValue)
:当properties对象中没有所指定的键值时,显示给定的默认值
load(InputStream inStream)
:从字节输入流中加载配置文件
load(Reader reader)
:从字符输入流中加载配置文件
store(OutputStream out, String comments)
:将Properties 对象以字节输出流写到.properties文件中,comments为配置文件说明;
store(Writer writer, String comments)
:将Properties 对象以字符输出流写到.properties文件中,comments为配置文件说明;
storeToXML(OutputStream os, String comment)
:将Properties 对象以字节输出流写到.xml文件中,comments为配置文件说明;
storeToXML(OutputStream os, String comment, String encoding)
:将Properties 对象以字节输出流写到.xml文件中,并指定编码,comments为配置文件说明;
class propertiesTest{
public static void main(String[] args) throws IOException {
Properties p=new Properties();
//.properties文件
p.load(new FileReader("src/db.properties"));
System.out.println(p.getProperty("jdbc.driver"));//com.mysql.jdbc.Driver
System.out.println(p.getProperty("driver", "没有该值"));
p.setProperty("jdbc.driver","com.mysql.jdbc.Driver1");
String remark="none";
p.store(new FileWriter("src/db.properties"),remark);
//.xml文件
p.loadFromXML(new FileInputStream("src/db.xml"));
System.out.println(p.getProperty("jdbc.driver"));
p.storeToXML(new FileOutputStream("src/db.xml"),"remark");
}
}
⑤TreeMap
TreeMap可以看作:TreeSet组成的key,value是任意引用类型;
特点:
- key唯一,key对象必须重写hashCode()与equals()
- 不可以插入null键值对
- key有序(自然排序、比较器排序)
- 查询快,增删慢
- 线程不安全
- key底层数据结构:红黑树
选择与使用:
- 一般情况下用HashMap
- 需要保证插入时顺序用LinkedHashMap
- 需要排序用TreeMap
- 考虑线程安全用Hashtable
八、Collections类
Collections类不同于Collection,前者是一个类,提供大量操作集合的方法,后者是一个集合接口。
常用方法:
【均为静态方法:Collections.xxx()】
-
List集合相关
void sort(List l)
:对list集合自然排序
void sort(List l,Comparator c)
:对list集合制订排序
void shuffle(List l)
:随机排序(洗牌)
void reverse(List l)
:反转集合
void swap(List l,int i,int j)
:交换索引i处与j处的元素
void rotate(List list,int m)
:集合中的元素向后移m个位置,在后面被遮盖的元素循环到前面来)。移动列表中的元素,负数向左移动,正数向右移动
int indexOfSubList(List list,List subList)
:查找subList在list中首次出现位置的索引
int lastIndexOfSubList(List list,List subList)
:查找subList在list中最后出现位置的索引
int copy(List m,List n)
:将集合n中的元素全部复制到m中,并且覆盖相应索引的元素)
void fill(List list,Object o)
:用对象o替换集合list中的所有元素
boolean replaceAll(List list,Object old,Object new)
:替换old元素为new元素,若要替换的值存在刚返回true,反之返回false -
Collection集合相关
int binarySearch(Collection,Object)
:查找指定集合中的元素,返回所查找元素的索引(首次出现)
Object max(Collection coll)
:返回最大元素
Object max(Collection coll, Comparator comp)
:根据自定义比较器,返回最大元素
Object min(Collection coll)
:返回最小元素
Object min(Collection coll, Comparator comp)
:根据自定义比较器,返回最小元素
int frequency(Collection Object o)
:返回指定集合中指定对象出现的次数 -
同步控制
Collections工具类中提供了多个synchronizedXxx()
方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问集合时线程的安全问题。 -
不可变集合
Collections有三类方法可返回一个不可变集合:
emptyXxx()
:返回一个空的不可变的集合对象
singletonXxx()
:返回一个只包含指定对象的,不可变的集合对象。
unmodifiableXxx()
:返回指定集合对象的不可变视图
class CollectionsTest{
public static void main(String[] args) {
ArrayList<Integer> arrayList=new ArrayList<>();
arrayList.add(32);
arrayList.add(54);
arrayList.add(64);
arrayList.add(12);
arrayList.add(12);
arrayList.add(75);
arrayList.add(96);
Collections.reverse(arrayList);//反转
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
System.out.println();
Collections.shuffle(arrayList);//洗牌
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
System.out.println();
Collections.sort(arrayList);//自然排序
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
System.out.println();
Collections.swap(arrayList,1,2);//交换指定下标元素值
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
System.out.println();
ArrayList<Integer> arrayList2=new ArrayList();
arrayList2.add(12);
//返回指定集合第一次出现的下标
int index1=Collections.indexOfSubList(arrayList,arrayList2);
System.out.println(index1);
//返回指定集合最后一次出现的下标
int index2=Collections.lastIndexOfSubList(arrayList,arrayList2);
System.out.println(index2);
//返回指定元素第一次出现的下标
System.out.println(Collections.binarySearch(arrayList, 12));
//返回指定元素出现的次数
System.out.println(Collections.frequency(arrayList, 12));
Collections.replaceAll(arrayList,12,13);//替换所有12为13
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
System.out.println();
Collections.fill(arrayList,0);//将所有元素替换为0
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
//使集合变成线程安全的集合
Collections.synchronizedCollection(arrayList);
}
}