使用Stream操作集合
在 java 中,可以采用流的形式对集合元素进行更方便的处理
Collection接口提供了一个 tream()方法,可以返回该集合对应的流,再调用流的各种方法即可对集合元素进行处理
public class StreamTest{
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public static void main(String[] args){
}
//独立使用Stream
@Test
public void m1(){
IntStream.Builder builder = IntStream.builder();//创建一个Builder
builder.add(23);
builder.add(12);
builder.add(99);//向该builder添加元素
IntStream is = builder.build();//获取对应的Stream
//Stream流中有四种类型的方法,中间方法,末端方法,有状态的方法,短路方法
//末端方法:对流的最终操作,当某个流对象执行末端方法后,该流将被“消耗”且不再可用
//末端方法只会执行一次,其他会报错
/*System.out.println("is 中所有元素最大值" + is.max().getAsInt());
System.out.println("is 中所有元素最小值" + is.min().getAsInt());
System.out.println("is 所有元素的平方是否大于 20" + is.allMatch(ele -> ele*ele > 20));//使用lambda表达式进行逻辑处理*/
//中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法,中间方法的返回值是另一个流
IntStream intStream = is.map(ele -> ele * 2 + 1);//根据转换规则对流中所有元素进行转换,并返回一个新流
IntStream intStream1 = intStream.filter(ele -> ele > 20);//过滤流中不满足大于20的元素
//使用流的forEach()方法遍历流中元素,注意,此时is,inStream流已经无法访问
intStream1.forEach(System.out::println);
//有状态的方法:该方法会给流增加一些新的属性,有状态的方法往往需要更大的性能开销
//短路方法:短路方法可以尽早结束对流的操作,不必检查所有元素
}
//使用集合返回的流
@Test
public void m2(){
//创建一个集合
List<String> list = new ArrayList<>();
list.add("书1");
list.add("书1");
list.add("书2");
//统计书1的数量
//因为要使用流末端方法和过滤方法,所以要不断获取集合对应的流
//注意使用Lambda表达式时必须是函数式接口(即接口中只有一个抽象方法)
System.out.println(list.stream().filter(ele -> ((String) ele).contains("书1")).count());//返回2
//统计书名等于二的书的个数
System.out.println(list.stream().filter(ele -> ((String) ele).length() == 2).count());//输出3
//同时可以将集合对应的流用mapToXxx(ToXxxFunction mapper)以其中的规则转换为不同的流进行操作
}
}
由此看来,使用Stream流可以方便处理集合,但要注意使用有状态的方法时往往需要更大的开销,使用末端方法后流会被“消耗”且不可再用