一.强大的Stram API
Stream 的操作步骤
-
创建 Stream
创建 Stream @Test public void test1(){ //1. Collection 提供了两个方法 stream() 与 parallelStream() List<String> list = new ArrayList<>(); Stream<String> stream = list.stream(); //获取一个顺序流 Stream<String> parallelStream = list.parallelStream(); //获取一个并行流 //2. 通过 Arrays 中的 stream() 获取一个数组流 Integer[] nums = new Integer[10]; Stream<Integer> stream1 = Arrays.stream(nums); //3. 通过 Stream 类中静态方法 of() Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6); //4. 创建无限流 //迭代 Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10); stream3.forEach(System.out::println); //生成 Stream<Double> stream4 = Stream.generate(Math::random).limit(2); stream4.forEach(System.out::println); }
-
中间操作
映射 1> map——接收 Lambda : 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 2> flatMap——接收一个函数作为参数: 将流中的每个值都换成另一个流,然后把所有流连接成一个流
@Test public void test1(){ Stream<String> str = emps.stream() .map((e) -> e.getName()); System.out.println("-------------------------------------------"); List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee"); Stream<String> stream = strList.stream() .map(String::toUpperCase); stream.forEach(System.out::println); Stream<Stream<Character>> stream2 = strList.stream() .map(TestStreamAPI1::filterCharacter); stream2.forEach((sm) -> { sm.forEach(System.out::println); }); System.out.println("---------------------------------------------"); Stream<Character> stream3 = strList.stream() .flatMap(TestStreamAPI1::filterCharacter); stream3.forEach(System.out::println); }
-
终止操作
1> allMatch——检查是否匹配所有元素 @Test public void test1(){ boolean bl = emps.stream() .allMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl); }
2> anyMatch——检查是否至少匹配一个元素 @Test public void test1(){ boolean bl1 = emps.stream() .anyMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl1); }
3 > noneMatch——检查是否没有匹配的元素 @Test public void test1(){ boolean bl2 = emps.stream() .noneMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl2); }
4>findFirst——返回第一个元素 @Test public void test2(){ Optional<Employee> op = emps.stream() .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())) .findFirst(); System.out.println(op.get()); }
5> findAny——返回当前流中的任意元素 @Test public void test2(){ Optional<Employee> op2 = emps.parallelStream() .filter((e) -> e.getStatus().equals(Status.FREE)) .findAny(); System.out.println(op2.get()); }
6> count——返回流中元素的总个数 @Test public void test3(){ long count = emps.stream() .filter((e) -> e.getStatus().equals(Status.FREE)) .count(); System.out.println(count); }
7> max——返回流中最大值 @Test public void test3(){ Optional<Double> op = emps.stream() .map(Employee::getSalary) .max(Double::compare); System.out.println(op.get()); }
8> min——返回流中最小值 @Test public void test3(){ Optional<Employee> op2 = emps.stream() .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(op2.get()); }
9>归约: reduce(T identity, BinaryOperator) / reduce(BinaryOperator): 可以将流中元素反复结合起来,得到一个值。 @Test public void test1(){ List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer sum = list.stream() .reduce(0, (x, y) -> x + y); System.out.println(sum); System.out.println("----------------------------------------"); Optional<Double> op = emps.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println(op.get()); } //需求:搜索名字中 “六” 出现的次数 @Test public void test2(){ Optional<Integer> sum = emps.stream() .map(Employee::getName) .flatMap(TestStreamAPI1::filterCharacter) .map((ch) -> { if(ch.equals('六')) return 1; else return 0; }).reduce(Integer::sum); System.out.println(sum.get()); }
10> collect:将流转换为其他形式。 接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法. @Test public void test3(){ //输出结果为list List<String> list = emps.stream() .map(Employee::getName) .collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("----------------------------------"); //输出结果为set Set<String> set = emps.stream() .map(Employee::getName) .collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("----------------------------------"); //输出结果为HashSet HashSet<String> hs = emps.stream() .map(Employee::getName) .collect(Collectors.toCollection(HashSet::new)); hs.forEach(System.out::println); } -------------------------------------------------- @Test public void test4(){ // 工资最大值 Optional<Double> max = emps.stream() .map(Employee::getSalary) .collect(Collectors.maxBy(Double::compare)); System.out.println(max.get()); // 工资最小值对应的员工 Optional<Employee> op = emps.stream() .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))); System.out.println(op.get()); //工资的总和 Double sum = emps.stream() .collect(Collectors.summingDouble(Employee::getSalary)); System.out.println(sum); //工资的平均值 Double avg = emps.stream() .collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println(avg); Long count = emps.stream() .collect(Collectors.counting()); System.out.println(count); System.out.println("--------------------------------------------"); }
11>分组:
//分组
@Test
public void test5(){
Map<Status, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
System.out.println(map);
}
----------------------------
//多级分组
@Test
public void test6(){
Map<Status, Map<String, List<Employee>>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(map);
}
12>分区:
@Test
public void test7(){
Map<Boolean, List<Employee>> map = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
System.out.println(map);
}
13>连接:
@Test
public void test8(){
String str = emps.stream()
.map(Employee::getName)
.collect(Collectors.joining(","));
System.out.println(str);//a,b,c
// ------------------
String str1 = emps.stream()
.map(Employee::getName)
.collect(Collectors.joining("," , "--", "----"));
System.out.println(str1);// --a,b,c----
}
并行流和串行流
计算1+2+3+…+10000000000L?
@Test
public void test3(){
long start = System.currentTimeMillis();
Long sum = LongStream.rangeClosed(0L, 10000000000L)
.parallel() //并行流开启
.sum();
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗费的时间为: " + (end - start)); //2061-2053-2086-18926
}