Collections
这里就是简单介绍一下, 之后我推荐第三方的库, 但是对于初学者的我们还是需要了解一下工具类的使用, JDK 中提供了一种集合操作的工具类 - Collections
public class Collections extends Object
1. 排序操作 (主要针对 List 接口相关)
编号 | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public static void reverse(List<?> list) | 普通方法 | 反转指定 List 集合中元素的顺序 |
2 | public static void shuffle(List<?> list) | 普通方法 | 对 List 中的元素进行随机排序 (洗牌) |
3 | public static void sort(List<T> list) | 普通方法 | 对 List 里的元素根据自然升序排序 |
4 | public static void sort(List<T> list, Comparator<? super T> c) | 普通方法 | 自定义比较器进行排序 |
5 | public static void swap(List<?> list, int i, int j) | 普通方法 | 将指定 List 集合中 i 处元素和 j 出元素进行交换 |
6 | public static void rotate(List<?> list,int distance) | 普通方法 | 将所有元素向右移位指定长度, 如果 distance 等于 size 那么结果不变 |
package com.shxt.demo05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
// 反转指定 List 集合中元素的顺序
Collections.reverse(list);
System.out.println("reverse 后的顺序:"+list);
// 对 List 中的元素进行随机排序 (洗牌)
Collections.shuffle(list);
System.out.println("shuffle 后的顺序:"+list);// 每次都不一样
// 对 List 里的元素根据自然升序排序
Collections.sort(list);
System.out.println("sort 后顺序:" + list);
// 将指定 List 集合中 i 处元素和 j 出元素进行交换
Collections.swap(list, 1, 3);
System.out.println("swap 后顺序:" + list);
// 将所有元素向右移位指定长度, 如果 distance 等于 size 那么结果不变
Collections.rotate(list, 2);
System.out.println("rotate 后顺序:" + list);
}
}
/*
运行结果:
reverse 后的顺序:[E, D, C, B, A]
shuffle 后的顺序:[B, A, E, D, C]
sort 后顺序:[A, B, C, D, E]
swap 后顺序:[A, D, C, B, E]
rotate 后顺序:[B, E, A, D, C]
*/
2. 查找和替换 (主要针对 Collection 接口相关)
编号 | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public static void binarySearch(List<? extends Comparable<? super T>> list, T key) | 普通方法 | 使用二分搜索法, 以获得指定对象在 List 中的索引, 前提是集合 < strong > 已经排序 |
2 | public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) | 普通方法 | 返回最大元素 |
3 | public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp) | 普通方法 | 根据自定义比较器, 返回最大元素 |
4 | public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) | 普通方法 | 返回最小元素 |
5 | public static <T> T min(Collection<? extends T> coll,Comparator<? super T> comp) | 普通方法 | 根据自定义比较器, 返回最小元素 |
6 | public static <T> void fill(List<? super T> list, T obj) | 普通方法 | 使用指定元素替换指定列表中的所有元素 |
7 | public static int frequency(Collection<?> c, Object o) | 普通方法 | 返回指定集合中指定对象出现的次数 |
8 | public static <T> boolean replaceAll(List list, T oldVal, T newVal) | 普通方法 | 替换 |
package com.shxt.demo05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo02 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("C");
list.add("D");
list.add("C");
list.add("C");
list.add("E");
System.out.println("max:" + Collections.max(list));
System.out.println("min:" + Collections.min(list));
System.out.println("frequency:" + Collections.frequency(list, "C"));
Collections.replaceAll(list, "C", "HanPang");
System.out.println("replaceAll 之后:" + list);
// 如果 binarySearch 的对象没有排序的话, 搜索结果是不确定的
System.out.println("binarySearch 在 sort 之前:" + Collections.binarySearch(list, "E"));
Collections.sort(list);
// sort 之后, 结果出来了
System.out.println("排序后的结果:" + list);
System.out.println("binarySearch 在 sort 之后:" + Collections.binarySearch(list, "E"));
Collections.fill(list, "^_^");
System.out.println("fill:" + list);
}
}
/*
运行结果:
max:E
min:A
frequency:4
replaceAll 之后:[A, B, HanPang, HanPang, D, HanPang, HanPang, E]
binarySearch 在 sort 之前:-3
排序后的结果:[A, B, D, E, HanPang, HanPang, HanPang, HanPang]
binarySearch 在 sort 之后: 3
fill:[^_^, ^_^, ^_^, ^_^, ^_^, ^_^, ^_^, ^_^]
*/
3. 其他方法
编号 | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public static boolean disjoint(Collection c1, Collection c2) | 普通方法 | 如果两个指定 collection 中没有相同的元素, 则返回 true. |
2 | public static <T> boolean addAll(Collection<? super T> c, T... elements) | 普通方法 | 一种方便的方式, 将所有指定元素添加到指定 collection 中 |
3 | public static <T> Comparator<T> reverseOrder() | 普通方法 | 返回一个比较器, 它强行反转指定比较器的顺序. 如果指定比较器为 null, 则此方法等同于 reverseOrder() |
package com.shxt.demo05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo03 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("悟空");
list.add("悟能");
list.add("悟净");
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
Collections.addAll(list1,"林冲","宋江","吴用","悟能");
Collections.addAll(list2,"林黛玉","贾宝玉","薛宝钗");
//disjoint 检查两个 Collection 是否的交集
boolean flag1 = Collections.disjoint(list,list1);
boolean flag2 = Collections.disjoint(list,list2);
System.out.println("list 和 list1 交集结果:"+flag1);
System.out.println("list 和 list2 交集结果:"+flag2);
// 利用 reverseOrder 倒序
Collections.sort(list1, Collections.reverseOrder());
System.out.println(list1);
}
}
/*
运行结果:
list 和 list1 交集结果: false
list 和 list2 交集结果: true
[林冲, 悟能, 宋江, 吴用]
*/
分割线: 方法量力而为
4. 设置不可变集合
何为 "不可变", 无法修改返回容器的内容, 注意, 这里指的是无法直接通过 set 或者 add 方法修改容器内 reference 的指向, 而不是禁止 reference 指向内容的修改.
为什么要使用不可变集合?
当对象被不可信的库调用时, 不可变形式是安全的;
不可变对象被多个线程调用时, 不存在竞态条件问题
不可变集合不需要考虑变化, 因此可以节省时间和空间. 所有不可变的集合都比它们的可变形式有更好的内存利用率 (分析和测试细节);
不可变对象因为有固定不变, 可以作为常量来安全使用.
编号 | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | emptyXxx() 开头的方法 | 普通方法 | 返回一个空的不可变的集合对象 (LIst/Map/Set) |
2 | singletonXxx() 开头的方法 | 普通方法 | 返回一个只包含指定对象的, 不可变的集合对象. |
3 | unmodifiableXxx() 开头的方法 | 普通方法 | 返回指定集合对象的不可变视图 |
package com.shxt.demo05;
import java.util.*;
public class Demo04 {
public static void main(String[] args) {
// 创建一个空的, 不可改变的 List 对象
List<?> list = Collections.emptyList();
System.out.println(list);
// 创建一个只有一个元素, 且不可改变的 map 对象
Map<String,String> map = Collections.singletonMap("name","悟空");
System.out.println(map);
// 创建一个普通的 Map 对象
Map<String,Integer> scores= new HashMap<String,Integer>();
scores.put("英语", 85);
scores.put("数学", 88);
// 返回普通的 Map 对象对应的不可变的版本
Map<String,Integer> unmodifiaMap= Collections.unmodifiableMap(scores);
// 若在不可变的版本中继续添加数据则会抛出 UnsupportedOperationException 异常
unmodifiaMap.put("Java",99);
}
}
/*
运行结果:
[]
{name = 悟空}
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
at com.shxt.demo05.Demo04.main(Demo04.java:20)
*/
5. 同步控制
Collections 工具类中提供了多个 synchronizedXxx 方法, 该方法返回指定集合对象对应的同步对象, 从而解决多线程并发访问集合时线程的安全问题. HashSet,ArrayList,HashMap 都是线程不安全的, 如果需要考虑同步, 则使用这些方法. 这些方法主要有: synchronizedSet,synchronizedSortedSet,synchronizedList,synchronizedMap,synchronizedSortedMap.
编号 | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public static Collection synchronizedCollection(Collection c) | 普通方法 | 返回指定 Collection 支持的同步 (线程安全的)Collection |
2 | public static List synchronizedList(List list) | 普通方法 | 返回指定列表支持的同步(线程安全的) 列表 |
3 | public static Map synchronizedMap(Map m) | 普通方法 | 返回由指定映射支持的同步 (线程安全的) 映射 |
4 | public static Set synchronizedSet(Set s) | 普通方法 | 返回指定 Set 支持的同步(线程安全的)Set |
package com.shxt.demo05;
import java.util.*;
public class Demo05 {
public static void main(String[] args) {
// 下面程序创建 4 个同步的集合对象
Collection c= Collections.synchronizedCollection(new ArrayList());
List list = Collections.synchronizedList(new ArrayList());
Set s= Collections.synchronizedSet(new HashSet());
Map m= Collections.synchronizedMap(new HashMap());
}
}
目前简单了解一下, 以后我们还会学习 google 开源的库 Guava
6.java.util.Collection 和 java.util.Collections 区别
java.util.Collection 是一个集合接口 (集合类的一个顶级接口). 它提供了对集合对象进行基本操作的通用接口方法. Collection 接口在 Java 类库中有很多具体的实现. Collection 接口的意义是为各种具体的集合提供了最大化的统一操作方式, 其直接继承接口有 List 与 Set.
java.util.Collections 是一个包装类 (工具类 / 帮助类). 它包含有各种有关集合操作的静态多态方法. 此类不能实例化, 就像一个工具类, 用于对集合中元素进行排序, 搜索以及线程安全等各种操作, 服务于 Java 的 Collection 框架.
来源: https://juejin.im/post/5a752b1c5188257a73499bb5