Collection集合的操作方法
1.Collections类操作
1.1Collections概述
Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、查找替换和复制等操作。
1.2排序(List)
- void reverse(List list):对指定 List 集合元素进行逆向排序。
- void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。
- void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。
- void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。
- void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。
- void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。
1.3查找替换
- int binarySearch(List list, Object key):使用二分搜索法搜索指定的 List 集合,以获得指定对象在 List 集合中的索引。如果要使该方法可以正常工作,则必须保证 List 中的元素已经处于有序状态。
- Object max(Collection coll):根据元素的自然顺序,返回给定集合中的最大元素。
- Object max(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最大元素。
- Object min(Collection coll):根据元素的自然顺序,返回给定集合中的最小元素。
- Object min(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最小元素。
- void fill(List list, Object obj):使用指定元素 obj 替换指定 List 集合中的所有元素。
- int frequency(Collection c, Object o):返回指定集合中指定元素的出现次数。
- int indexOfSubList(List source, List target):返回子 List 对象在父 List 对象中第一次出现的位置索引;如果父 List 中没有出现这样的子 List,则返回 -1。
int lastIndexOfSubList(List source, List target):返回子 List 对象在父 List 对象中最后一次出现的位置索引;如果父 List 中没有岀现这样的子 List,则返回 -1。
boolean replaceAll(List list, Object oldVal, Object newVal):使用一个新值 newVal 替换 List 对象的所有旧值 oldVal。
1.4复制
Collections 类的 copy() 静态方法用于将指定集合中的所有元素复制到另一个集合中。执行 copy() 方法后,目标集合中每个已复制元素的索引将等同于源集合中该元素的索引。
语法格式:void copy(List <? super T> dest,List<? extends T> src)
2.Predicate操作Collection(Java8新增)
2.1 Pridicate概述
- Predicate 也是函数式接口,相当于一个过滤器,因此可使用 Lambda 表达式作为参数。
Java 8 起为 Collection 集合新增了一个 removeIf(Predicate filter) 方法,该方法将会批量删除符合 filter 条件的所有元素。
2.2 示例用法:
//方法显示符合要求的对象
public static void callInf(Collection col, Predicate p){
final Iterator its = col.iterator();
while(its.hasNext()){
Object temp = its.next();
if (p.test(temp)){
System.out.println(temp);
}
}
}
main:
set.removeIf(num -> num < 20); //删除指定元素
callInf(set, num -> (Integer)num > 20); 显示指定对象
3.Stream操作Collection
3.1 Stream分类与概述
Java 8 还新增了 Stream、IntStream、LongStream、DoubleStream 等流式 API,这些 API 代表多个支持串行和并行聚集操作的元素。上面 4 个接口中,Stream 是一个通用的流接口,而 IntStream、LongStream、 DoubleStream 则代表元素类型为 int、long、double 的流。
Java 8 还为上面每个流式 API 提供了对应的 Builder,例如 Stream.Builder、IntStream.Builder、LongStream.Builder、DoubleStream.Builder,开发者可以通过这些 Builder 来创建对应的流。
3.2 Stream使用步骤
- 使用 Stream 或 XxxStream 的 builder() 类方法创建该 Stream 对应的 Builder。
- 重复调用 Builder 的 add() 方法向该流中添加多个元素。
- 调用 Builder 的 build() 方法获取对应的 Stream。
- 调用 Stream 的聚集方法。
注:在上面 4 个步骤中,第 4 步可以根据具体需求来调用不同的方法,Stream 提供了大量的聚集方法供用户调用,具体可参考 Stream 或 XxxStream 的 API 文档。对于大部分聚集方法而言,每个 Stream 只能执行一次。
3.3 示例
/*1. 使用 Stream 或 XxxStream 的 builder() 类方法创建该 Stream 对应的 Builder。
2. 重复调用 Builder 的 add() 方法向该流中添加多个元素。
3. 调用 Builder 的 build() 方法获取对应的 Stream。*/
IntStream is = IntStream.builder().add(20).add(13).add(-2).add(18).build();
// 下面调用聚集方法的代码每次只能执行一行(对于大部分聚集方法而言,每个 Stream 只能执行一次。)
System.out.println("is 所有元素的最大值:" + is.max().getAsInt());
System.out.println("is 所有元素的最小值:" + is.min().getAsInt());
System.out.println("is 所有元素的总和:" + is.sum());
System.out.println("is 所有元素的总数:" + is.count());
System.out.println("is 所有元素的平均值:" + is.average());
System.out.println("is所有元素的平方是否都大于20: " + is.allMatch(ele -> ele * ele > 20));
System.out.println("is是否包含任何元素的平方大于20 : " + is.anyMatch(ele -> ele * ele > 20));
// 将is映射成一个新Stream,新Stream的每个元素是原Stream元素的2倍+1
IntStream newIs = is.map(ele -> ele * 2 + 1);
// 使用方法引用的方式来遍历集合元素
newIs.forEach(System.out::println); // 输岀 41 27 -3 37
3.4 Stream中的一些方法
Stream 提供了大量的方法进行聚集操作,这些方法既可以是“中间的”(intermediate),也可以是 "末端的"(terminal)。
- 中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法。上面程序中的 map() 方法就是中间方法。中间方法的返回值是另外一个流。
- 末端方法:末端方法是对流的最终操作。当对某个 Stream 执行末端方法后,该流将会被“消耗”且不再可用。上面程序中的 sum()、count()、average() 等方法都是末端方法。
除此之外,关于流的方法还有如下两个特征。
- 有状态的方法:这种方法会给流增加一些新的属性,比如元素的唯一性、元素的最大数量、保证元素以排序的方式被处理等。有状态的方法往往需要更大的性能开销。
- 短路方法:短路方法可以尽早结束对流的操作,不必检查所有的元素
3.4.1 常用中间方法
3.4.2 常用末端方法
3.4.3 流式API操作集合
Java 8 允许使用流式 API 来操作集合,Collection 接口提供了一个 stream() 默认方法,该方法可返回该集合对应的流,接下来即可通过流式 API 来操作集合元素。由于 Stream 可以对集合元素进行整体的聚集操作,因此 Stream 极大地丰富了集合的功能。
示例:修改Predicate的callInf方法
set.stream().filter(num -> num > 20).forEach(System.out::println);
4.疑问
- Consumer接口的使用