JDK1.8之后Stream流操作学习

1.stream排序
string集合
List<String> sortStringList = new ArrayList<>();
        sortStringList.add("F001");
        sortStringList.add("F040");
        sortStringList.add("F040");
        sortStringList.add("F005");
        sortStringList.add("F047");
        sortStringList.add("F005");
        sortStringList.add("F056");
        sortStringList.add("F999");
System.out.println("排序之前的List:" + sortStringList);
//方式一	默认为正序排序,若想倒序排序则将o1、o2倒过来即可!
Comparator<Object> comparator = new Comparator<Object>() {
    @Override
    public int compare(Object o1, Object o2) {
        Collator collator = Collator.getInstance();
        return collator.getCollationKey(String.valueOf(o1)).compareTo(collator.getCollationKey(String.valueOf(o2)));
    }
};
Collections.sort(sortStringList,comparator);
System.out.println("排序之后的List:" + sortStringList);
//方式二	这里是倒序排序,若去掉‘reversed()’则为正序排序
sortStringList.sort(Comparator.comparing(item -> String.valueOf(item)).reversed());
System.out.println("排序之后的List:" + sortStringList);
对象集合
        AlarmInfo alarmInfo = new AlarmInfo("F001",50,20,"Aily");
        AlarmInfo alarmInfo2 = new AlarmInfo("F086",30,30,"Jerry");
        AlarmInfo alarmInfo3 = new AlarmInfo("F026",58,25,"Tony");
        AlarmInfo alarmInfo4 = new AlarmInfo("F061",109,27,"Zeroe");
        List<AlarmInfo> alarmInfos = new ArrayList<>();
        alarmInfos.add(alarmInfo);
        alarmInfos.add(alarmInfo2);
        alarmInfos.add(alarmInfo3);
        alarmInfos.add(alarmInfo4);

        Stream<AlarmInfo> infoStream = alarmInfos.stream();
        infoStream = infoStream.sorted(Comparator.nullsLast(Comparator.comparing(
        	alarmInfo1 -> alarmInfo1.getWindField())));

        infoStream.forEach(alarmInfo1 -> {
            System.out.println(alarmInfo1.toString());
        });
 List<Map<String,Object>> mapList = Lists.newArrayList();
    for (AlarmInfo alerm:alarmInfos
         ) {
        Map<String,Object> map = beanToMap(alerm);
        mapList.add(map);
    }
    Stream<Map<String,Object>> mapStream = mapList.stream().sorted(Comparator.comparing(item -> {
        Map<String,Object> map = (Map<String,Object>)item;
        return String.valueOf(map.get("message"));
    }).reversed());

    mapStream.forEach(item -> {
        System.out.println(item);
    });
2.distinct去重、list转string
	String listStr = sortStringList.stream().distinct().collect(Collectors.joining(","));
    System.out.println(listStr);
3.filter过滤
list = list.stream().filter(record -> 
	record.endsWith("40")).collect(Collectors.toList());
list.forEach(item -> {
    System.out.println(item);
});
4.map获取对象中某个值的集合
List<String> windFields = alarmInfos.stream().map(item ->
        String.valueOf(item.getWindField())).collect(Collectors.toList());
System.out.println(windFields.toString());
5.使用collect()生成Map

构造对象

@Data
class Student{
    String name;    //姓名
    String class1;  //班级
    Integer age;    //年龄
    Integer score;  //成绩
    public Student (String name,String class1,Integer age,Integer score){
        this.name = name;
        this.class1 = class1;
        this.age = age;
        this.score = score;
    }
}

构造对象集合

List<Student> list = new ArrayList<>();
        list.add(new Student("李思","一班",16,95));
        list.add(new Student("王武","三班",15,84));
        list.add(new Student("赵柳","三班",17,79));
        list.add(new Student("Lusay","二班",16,90));
        list.add(new Student("Weufa","一班",18,80));
        list.add(new Student("Cary","二班",14,100));

stream()生成Map对象一般分为一下三种情况:

  1. 使用Collectors.toMap()生成的收集器,用户需要指定如何生成Mapkeyvalue
  2. 使用Collectors.partitioningBy()生成的收集器,对元素进行二分区操作时用到。
  3. 使用Collectors.groupingBy()生成的收集器,对元素做group操作时用到。

情况1:使用toMap()生成的收集器,这种情况是最直接的,前面例子中已提到,这是和Collectors.toCollection()并列的方法。下面代码是对每个学生进行分组,对每个学生的成绩进行处理

Map<Student, String> collect2 = list.parallelStream().collect(Collectors.toMap(Function.identity(),item->computer(item)));
for(Map.Entry<Student, String> map : collect2.entrySet()){
    System.out.println(map);
}
//结果打印
//Student(name=王武, class1=三班, age=15, score=84)=优秀
//Student(name=李思, class1=一班, age=16, score=95)=优秀
//Student(name=Weufa, class1=一班, age=18, score=80)=一般般~
//Student(name=Lusay, class1=二班, age=16, score=90)=优秀
//Student(name=Cary, class1=二班, age=14, score=100)=优秀
//Student(name=赵柳, class1=三班, age=17, score=79)=一般般~

情况2:使用partitioningBy()生成的收集器,这种情况适用于将Stream中的元素依据某个二值逻辑(满足条件,或不满足)分成互补相交的两部分,比如男女性别、成绩及格与否等。下列代码展示将学生分成一班和其他班两部分。

        Map<Boolean, List<Student>> collect1 = list.stream().collect(Collectors.partitioningBy(item -> item.getClass1() == "一班"));
        for(Map.Entry<Boolean, List<Student>> map : collect1.entrySet()){
            System.out.println(map);
        }
//		  结果打印
//        false=[Student(name=王武, class1=三班, age=15, score=84), Student(name=赵柳, class1=三班, age=17, score=79), Student(name=Lusay, class1=二班, age=16, score=90), Student(name=Cary, class1=二班, age=14, score=100)]
//        true=[Student(name=李思, class1=一班, age=16, score=95), Student(name=Weufa, class1=一班, age=18, score=80)]

情况3:使用groupingBy()生成的收集器,这是比较灵活的一种情况。跟SQL中的group by语句类似,这里的groupingBy()也是按照某个属性对数据进行分组,属性相同的元素会被对应到Map的同一个key上。下列代码展示将学生按班级进行分组:

        Map<String, List<Student>> collect = list.stream().collect(Collectors.groupingBy(item -> item.getClass1()));
        for(Map.Entry<String,List<Student>> map : collect.entrySet()){
            System.out.println(map);
        }
//        结果打印:
//        一班=[Student(name=李思, class1=一班, age=16, score=95), Student(name=Weufa, class1=一班, age=18, score=80)]
//        二班=[Student(name=Lusay, class1=二班, age=16, score=90), Student(name=Cary, class1=二班, age=14, score=100)]
//        三班=[Student(name=王武, class1=三班, age=15, score=84), Student(name=赵柳, class1=三班, age=17, score=79)]

以上只是分组的最基本用法,有些时候仅仅分组是不够的。在SQL中使用group by是为了协助其他查询,比如1. 先将学生按照班级分组,2. 然后统计每个班级的人数。Java类库设计者也考虑到了这种情况,增强版的groupingBy()能够满足这种需求。增强版的groupingBy()允许我们对元素分组之后再执行某种运算,比如求和、计数、平均值、类型转换等。这种先将元素分组的收集器叫做上游收集器,之后执行其他运算的收集器叫做下游收集器(downstream Collector)。

        Map<String, Long> collect3 = list.stream().collect(Collectors.groupingBy(item -> item.getClass1(), Collectors.counting()));
        for (Map.Entry<String, Long> map : collect3.entrySet()) {
            System.out.println(map);
        }
//        结果打印:
//        一班=2
//        二班=2
//        三班=2

上面代码的逻辑是不是越看越像SQL?高度非结构化。还有更狠的,下游收集器还可以包含更下游的收集器,这绝不是为了炫技而增加的把戏,而是实际场景需要。考虑将学生按照班级分组的场景,如果我们想得到每个学生的名字(字符串),而不是一个个Student对象,可通过如下方式做到:

        Map<String, List<String>> collect3 = list.stream().collect(Collectors.groupingBy(Student :: getClass1, Collectors.mapping(
            Student::getName,Collectors.toList()
        )));
        for (Map.Entry<String, List<String>> map : collect3.entrySet()) {
            System.out.println(map);
        }
//        结果打印:
//        一班=[李思, Weufa]
//        二班=[Lusay, Cary]
//        三班=[王武, 赵柳]

持续更新中~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值