文章目录
collections类使用
- Collections是JDK提供的工具类,同样位于
java.util
包中。它提供了一系列静态方法
,能更方便地操作各种集合。
1.addAll()
boolean addAll(Collection<? super T> c, T... elements) { ... }
addAll()方法可以给一个Collection类型的集合添加若干元素。因为方法类型是Collection,所以我们可以传入List,Set等各种集合类型。
2.创建空集合
- 创建空List:
List<T> emptyList()
- 创建空Map:
Map<K, V> emptyMap()
- 创建空Set:
Set<T> emptySet()
要注意到返回的空集合是不可变集合,无法向其中添加或删除元素
。
此外,也可以用各个集合接口提供的of(T…)方法创建空集合。例如,以下创建空List的两个方法是等价的:
List<String> list1 = List.of();
List<String> list2 = Collections.emptyList();
3.创建单元素集合
- 创建一个元素的List:
List<T> singletonList(T o)
- 创建一个元素的Map:
Map<K, V> singletonMap(K key, V value)
- 创建一个元素的Set:
Set<T> singleton(T o)
要注意到返回的单元素集合也是不可变集合,无法向其中添加或删除元素
此外,也可以用各个集合接口提供的of(T…)方法创建单元素集合,实际上,使用List.of(T...)
更方便,因为它既可以创建空集合
,也可以创建单元素集
合,还可以创建任意个元素的集合
:
List<String> list1 = List.of(); // empty list
List<String> list2 = List.of("apple"); // 1 element
List<String> list3 = List.of("apple", "pear"); // 2 elements
List<String> list4 = List.of("apple", "pear", "orange"); // 3 elements
List.of(),Set.of),Map.of()
是JDK9
新增的方法
4.排序
Collections.sort()
可以直接给List集合排序,或者使用比较器Comparable/Comparator指定条件排序
- <T extends Comparable<? super T>> void sort(List list)
- void sort(List list, Comparator<? super T> c)
- void sort(Comparator<? super E> c)
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("pear");
list.add("orange");
// 排序前:
System.out.println(list);
Collections.sort(list);
// 排序后:
System.out.println(list);
}
5.洗牌
Collections.shuffle()
提供了洗牌算法,即传入一个有序的List,可以随机打乱List内部元素的顺序,即对集合进行随机排序
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i=0; i<10; i++) {
list.add(i);
}
// 洗牌前:
System.out.println(list);
Collections.shuffle(list);
// 洗牌后:
System.out.println(list);
}
6.不可变集合
Collections还提供了一组方法把可变集合封装成不可变集合:
- 封装成不可变List:
List<T> unmodifiableList(List<? extends T> list)
- 封装成不可变Set:
Set<T> unmodifiableSet(Set<? extends T> set)
- 封装成不可变Map:
Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m)
这种封装实际上是通过创建一个代理对象,拦截掉所有修改方法实现的。我们来看看效果:
public static void main(String[] args) {
List<String> mutable = new ArrayList<>();
mutable.add("apple");
mutable.add("pear");
// 变为不可变集合:
List<String> immutable = Collections.unmodifiableList(mutable);
immutable.add("orange"); // UnsupportedOperationException!
}
然而,继续对原始的可变List
进行增删
是可以的,并且,会直接影响到封装后的“不可变”List:
public static void main(String[] args) {
List<String> mutable = new ArrayList<>();
mutable.add("apple");
mutable.add("pear");
// 变为不可变集合:
List<String> immutable = Collections.unmodifiableList(mutable);
mutable.add("orange");
System.out.println(immutable);
}
因此,如果我们希望把一个可变List封装成不可变List
,那么返回不可变List后,最好立刻让GC回收可变List,这样可以保证后续操作不会意外改变原始对象
,从而造成“不可变”List变化
了:
public static void main(String[] args) {
List<String> mutable = new ArrayList<>();
mutable.add("apple");
mutable.add("pear");
// 变为不可变集合:
List<String> immutable = Collections.unmodifiableList(mutable);
// 立刻扔掉mutable的引用:
mutable = null;
System.out.println(immutable);
}
7. 线程安全集合
Collections还提供了一组方法,可以把线程不安全的集合变为线程安全的集合:
- 变为线程安全的List:
List<T> synchronizedList(List<T> list)
- 变为线程安全的Set:
Set<T> synchronizedSet(Set<T> s)
- 变为线程安全的Map:
Map<K,V> synchronizedMap(Map<K,V> m)
因为从Java 5
开始,引入了更高效的并发集合类
,所以上述这几个同步方法已经没有什么用了
。
8.查询指定下标
binarySearch(Collection,Object)方法的使用(含义:查找指定集合中的元素,返回所查找元素的索引
public static void main(String[] args) {
List c = new ArrayList();
c.add("w");
c.add("o");
c.add("r");
c.add("l");
c.add("d");
System.out.println("TAG", "初始集合:"+c);//[w, o, r, l, d]
int m = Collections.binarySearch(c, "l");
System.out.println("TAG", "找元素的索引:"+m);//-1
}
9.indexOfSubList
int indexOfSubList(List<?> source, List<?> target)
查找subList在list中首次出现位置的索引
public static void main(String[] args) {
List list = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:"+list);//[one, two, three, four, five, six, siven]
List subList = Arrays.asList("three four five six".split(" "));
System.out.println("TAG", "子集合:"+subList);//[three, four, five, six]
System.out.println("TAG", "子集合首次出现位置的索引:"+Collections.indexOfSubList(list, subList));//2
}
10.lastIndexOfSubList
int lastIndexOfSubList(List<?> source, List<?> target)
查找subList在list中最后出现位置的索引
public static void main(String[] args) {
List list = Arrays.asList("one two three four five six siven one two three four five six siven".split(" "));
System.out.println(("TAG", "初始集合:"+list);//[one, two, three, four, five, six, siven, one, two, three, four, five, six, siven]
List subList = Arrays.asList("three four five six".split(" "));
System.out.println("TAG", "子集合:"+subList);//[three, four, five, six]
System.out.println("TAG", "子集合首次出现位置的索引:"+Collections.indexOfSubList(list, subList));//2
System.out.println("TAG", "子集合最后出现位置的索引:"+Collections.lastIndexOfSubList(list, subList));//9
}
11.替换集合中指定元素
<T> boolean replaceAll(List<T> list, T oldVal, T newVal)
替换指定元素为某元素,若要替换的值(旧元素)存在刚返回true,反之返回false
public static void main(String[] args) {
List list = Arrays.asList("old one two three four old five six siven old".split(" "));
System.out.println("TAG", "初始集合:"+list);//[old, one, two, three, four, old, five, six, siven, old]
System.out.println("TAG", "替换值是否存在:"+Collections.replaceAll(list, "old", "two"));//true
System.out.println("TAG", "替换后集合:"+list);//[new, one, two, three, four, new, five, six, siven, new]
}
12.反转List集合中元素的顺序
void reverse(List<?> list)
public static void main(String[] args) {
List list = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:" + list);//[one, two, three, four, five, six, siven]
Collections.reverse(list);
System.out.println("TAG", "反转后集合:" + list);//[siven, six, five, four, three, two, one]
}
13.集合中的元素向后移m个位置
void rotate(List<?> list, int distance) 集合中的元素向后移m个位置,在后面被遮盖的元素循环到前面来
public static void main(String[] args) {
List list = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:" + list);//[one, two, three, four, five, six, siven]
Collections.rotate(list, 2);
System.out.println("TAG", "旋转后集合:" + list);//[six, siven, one, two, three, four, five]
}
14.拷贝List集合
<T> void copy(List<? super T> dest, List<? extends T> src)
将集合n中的元素全部复制到m中,并且覆盖相应索引的元素((从0开始覆盖,后面的元素向后移))
public static void main(String[] args) {
List m = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:" + m);//[one, two, three, four, five, six, siven]
List n = Arrays.asList("我是 复制 过来的哈".split(" "));
System.out.println("TAG", "待复制集合:" + n);//[我是, 复制, 过来的哈]
Collections.copy(m, n);
System.out.println("TAG", "复制后集合:" + m);//[我是, 复制, 过来的哈, four, five, six, siven]
}
15.交换List集合/数组中指定元素索引的位置
- void swap(List<?> list, int i, int j)
- void swap(Object[] arr, int i, int j)
交换集合中指定元素索引的位置
public static void main(String[] args) {
List m = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:" + m);//[one, two, three, four, five, six, siven]
Collections.swap(m, 2, 3);
System.out.println("TAG", "交换后集合:" + m);//[one, two, four, three, five, six, siven]
}
16. 用一个元素替换List集合所有元素
** void fill(List<? super T> list, T obj) 用对象obj替换集合list中的所有元素 **
public static void main(String[] args) {
List m = Arrays.asList("one two three four five six siven".split(" "));
System.out.println("TAG", "初始集合:" + m);//[one, two, three, four, five, six, siven]
Collections.fill(m, "haha12345");
System.out.println("TAG", "替换后集合:" + m);//[haha12345, haha12345, haha12345, haha12345, haha12345, haha12345, haha12345]
}