lambda表达式Stream流学习八、九—Stream的终止操作 : 查找与匹配、归约与收集、分组

Java8的lambda表达式学习记录—lambda表达式Stream流学习八、久—Stream的中间操作 : 查找与匹配、归约与收集、分组

一,查找与匹配

  Stream流的终止操作,以下操作都是Stream.调用:

  1. allMatch——检查是否匹配所有元素,返回值为boolean
  2. anyMatch——检查是否至少匹配一个元素,返回值为boolean
  3. noneMatch——检查是否没有匹配的元素,返回值为boolean
  4. findFirst——返回第一个元素,返回值为Optional集合
  5. findAny——返回当前流中的任意元素,返回值为Optional
  6. count——返回流中元素的总个数,返回值为Long
  7. max——返回流中的最大值,返回值为Optional
  8. min——返回流中的最小值,返回值为Optional
//Employee对象新增枚举类型
public class Employee {
	private status status;
    public enum status{
       FREE,
       BUSY,
       VOCATION;
    }
}
@Test
public void test1(){
	List<Employee> list = Arrays.asList(
	       new Employee("张三", 18, 9999.99, Employee.status.FREE),//枚举类型
	       new Employee("李四", 20, 7777.77, Employee.status.BUSY),
	       new Employee("王五", 36, 5555.55, Employee.status.VOCATION),
	       new Employee("赵六", 50, 3333.33, Employee.status.FREE),
	       new Employee("田七", 10, 2222.22, Employee.status.VOCATION)
	);

    Boolean b1 = list.stream().allMatch((e) -> e.getStatus().equals(Employee.status.BUSY));//.allMatch匹配所有
    System.out.println(b1);//是否所有的都和BUSY相等, false
    
    Boolean b2 = list.stream().anyMatch(e -> e.getStatus().equals(Employee.status.BUSY));//.anyMatch匹配至少一个
    System.out.println(b2);//至少有一个和BUSY相等, true
    
    Boolean b3 = list.stream().noneMatch(e -> "花招虫".equals(e.getName()));//.noneMatch是否没有匹配的元素
    System.out.println(b3);//没有值与之相匹配, true
    
    Optional<Employee> op = list.stream().sorted(Comparator.comparingDouble(Employee::getSalary)).findFirst();//.findFirst返回第一个元素
    System.out.println(op);//Optional[Employee{name='田七', age=10, salary=2222.22, status=VOCATION}]
    /*
    Optional 是Java8中新推出的用来避免空指针异常的函数型接口,它会自动将可能为空的值放入里面,然后做处理.
     */

    Optional<Employee> op2 = list.stream().filter(e -> Employee.status.FREE.equals(e.getStatus())).findAny();//.findAny在当前流中随机返回一个元素
    System.out.println(op2);//Optional[Employee{name='张三', age=18, salary=9999.99, status=FREE}]

    long l = list.stream().count();
    System.out.println(l);//5

    Optional<Employee> op3 = list.stream().max(Comparator.comparingDouble(Employee::getSalary));//.max查找流中最大元素值
    System.out.println(op3);//Optional[Employee{name='张三', age=18, salary=9999.99, status=FREE}]
}

//练习题 : 1)查出list集合中工资最多的人的信息 2)求集合中最大工资是多少
public void test2(){
	Optional<Employee> op = list.stream().sorted(Comparator.comparingDouble(Employee::getSalary)).findFirst();
    System.out.println(op);//Optional[Employee{name='田七', age=10, salary=2222.22, status=VOCATION}]
    Optional<Double> op2 = list.stream().map(Employee::getSalary).max(Double::compareTo);
	System.out.println(op2);//Optional[9999.99]
}

二,归约与收集

//新建测试集合
List<Employee> emps = Arrays.asList(
        new Employee("张三", 18, 9999.99, Employee.status.FREE),//枚举类型
        new Employee("李四", 20, 7777.77, Employee.status.BUSY),
        new Employee("王五", 36, 5555.55, Employee.status.VOCATION),
        new Employee("赵六", 50, 3333.33, Employee.status.FREE),
        new Employee("田七", 10, 2222.22, Employee.status.VOCATION)
);

  归约 : 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);//0是x的起始值,y的起始值是1,因为给了起始值,所以必然不为空,不需要用Optional封装
    System.out.println(sum);

    //求所有人的工资总和
    Optional<Double> d = emps.stream().map(Employee::getSalary).reduce(Double::sum);//Double::sum JDK1.8新增的静态方法,计算两个double类型的值
    //因为没有指定起始值,java判断d可能为空,所以封装了Optional<>
    System.out.println(d);
}

  收集 : Stream.collect——将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素汇总的方法。

@Test
public void test2(){
    List<String> l1 = emps.stream().map(Employee::getName).collect(Collectors.toList());
    System.out.println(l1);

    HashSet<String> set = emps.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
    //Collectors.toCollection(Supplier<T>) 可以转换为任意集合
    set.forEach(System.out::println);
}
//收集的方法求总数、平均值、总和、最大值、最小值
@Test
public void test3(){
    System.out.println(emps.stream().collect(Collectors.counting()));//总数
    System.out.println(emps.stream().collect(Collectors.averagingDouble(Employee::getSalary)));//平均值
    System.out.println(emps.stream().collect(Collectors.summingDouble(Employee::getSalary)));//总和
    Optional<Employee> max =  emps.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
    System.out.println(max.get());
    Optional<Double> min = emps.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
    System.out.println(min.get());
}

三,分组与分区

  分组函数 : Stream.collect(Collectors.groupingBy()),可以传两个参数进行多条件分组

@Test
public void test4(){
    Map<Employee.status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));//groupingBy分组函数
    System.out.println(map);

    //多条件分组,先按status分组,然后再按年龄分组
    Map<Employee.status, Map<String, List<Employee>>> map2 = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
        if (e.getAge() <= 35){
            return "青年";
        }else if (e.getAge() <= 50){
            return "中年";
        }else{
            return "老年";
        }
    })));
    System.out.println(map2);
}
//{FREE=[Employee{name='张三', age=18, salary=9999.99, status=FREE}, Employee{name='赵六', age=50, salary=3333.33, status=FREE}], VOCATION=[Employee{name='王五', age=36, salary=5555.55, status=VOCATION}, Employee{name='田七', age=10, salary=2222.22, status=VOCATION}], BUSY=[Employee{name='李四', age=20, salary=7777.77, status=BUSY}]}
//{FREE={青年=[Employee{name='张三', age=18, salary=9999.99, status=FREE}], 中年=[Employee{name='赵六', age=50, salary=3333.33, status=FREE}]}, VOCATION={青年=[Employee{name='田七', age=10, salary=2222.22, status=VOCATION}], 中年=[Employee{name='王五', age=36, salary=5555.55, status=VOCATION}]}, BUSY={青年=[Employee{name='李四', age=20, salary=7777.77, status=BUSY}]}}

  分区函数 : Stream.collect(Collectors.partitioningBy()),根据参数进行分组,参数返回值为boolean

@Test
public void test5(){
    Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 5000));
    System.out.println(map);
}
//{false=[Employee{name='赵六', age=50, salary=3333.33, status=FREE}, Employee{name='田七', age=10, salary=2222.22, status=VOCATION}], true=[Employee{name='张三', age=18, salary=9999.99, status=FREE}, Employee{name='李四', age=20, salary=7777.77, status=BUSY}, Employee{name='王五', age=36, salary=5555.55, status=VOCATION}]}

四,collect的其他操作

  获取数据处理对象 : stream.collect(Collectors.summarizingDouble()),该对象可以直接拿来求最大最小值,平均数。

@Test
public void test6(){
    DoubleSummaryStatistics b = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
    System.out.println(b.getMax());
    System.out.println(b.getMin());
    System.out.println(b.getAverage());
}

  拼接字符串 : stream.map().collect(Collectors.joining()),可以直接拼接流中指定的元素,可指定凭借符号,一个参数时为拼接符号,三个参数为拼接符号、起始值、结束值。

@Test
public void test7(){
    String names = emps.stream().map(Employee::getName).collect(Collectors.joining(",", "姓名:", "。"));
    System.out.println(names);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值