组织部网站建设方案,单页网站赚钱,用啥网站做首页,北京建站公司兴田德润专业背景
jdk8的stream流能方便的排序#xff0c;但是每次都要查资料#xff0c;非常不方便#xff0c;不确定#xff0c;所以这次直接弄懂#xff0c;不再迷茫。 转载请注明来源#xff0c;创作不易#xff0c;请多多支持。 基础排序
stream流 大家应该都比较熟悉了…背景
jdk8的stream流能方便的排序但是每次都要查资料非常不方便不确定所以这次直接弄懂不再迷茫。 转载请注明来源创作不易请多多支持。 基础排序
stream流 大家应该都比较熟悉了毕竟jdk8出来多久了言简意赅的讲解下
stream 流提供的排序的方法其实就两个 一个是无参的 StreamT sorted(); 一个是有参的 StreamT sorted(Comparator? super T comparator);
基础写法-无参
无参的排序很简单按照默认排序测试代码如下 DataBuilderpublic static class User {private String username;private Integer age;}Testpublic void StreamSort() {ListString list1 Lists.newArrayList(1, 2, 01, 02, 10, 11, a);ListInteger list2 Lists.newArrayList(1, 2, 0, 3, 7);ListBoolean list3 Lists.newArrayList(true, false, true, false, false);ListUser list4 Lists.newArrayList(User.builder().age(1).build(), User.builder().age(2).build(), User.builder().age(3).build());list1.stream().sorted().forEach(p - System.out.print(p ));}结论 其实只要知道基础类型默认是怎么排序的就好了对象类型本质还是指定到基础类型去记住一个词 点名(从小到大)
1、字符串排序结果是 01 02 1 10 11 2 a,字符串比较很简单就是字符依次比较从小到大第一位相同比第二位依次排序。
2、数值类型排序结果 0 1 2 3 7,数值类型的都是一样的规律从小到大 和 报数一样
3、布尔类型排序结果 false false false true true,可以类比 0是false 1是true 约定俗成 0为false 1为true, 依然是上升趋势
基础写法-有参
Comparator 是一个专门排序用的接口,只有一个核心方法 int compare(T o1, T o2);
严格的写法
一个匿名内部类实现排序的逻辑 list2.stream().sorted(new ComparatorInteger() {Overridepublic int compare(Integer p1, Integer p2) {return p1 - p2;}}).forEach(p - System.out.print(p ));jdk8可以用lambda表达式简写非数值类型的需要自定义规则 (p1, p2) - {return p1 - p2;}或者 进一步简写 (p1, p2) - p1 - p2常用便捷写法
大部分其实都是数值比较,除了非数值类型的需要自定义规则
比如要实现默认的字符串的比较可以自定义以下逻辑 list1.stream().sorted((p1, p2) - {char[] chars1 p1.toCharArray();char[] chars2 p2.toCharArray();//取短数组长度for (int i 0; i Math.min(chars1.length, chars2.length); i) {if (chars1[i] ! chars2[i]) {return chars1[i] - chars2[i];}}return 0;}).forEach(p - System.out.print(p ));但是对于完全的数值比较其实就按照默认的比较即可给Stream 排序的值即可,特别是对象只需要指定字段即可 list4.stream().sorted(Comparator.comparingInt(User::getAge)).forEach(p - System.out.print(p ));支持的数值方法有 comparingInt 、comparingLong、comparingDouble
基础写法-倒序
默认的排序是点名,从小到大而有时候我们需要从大到小
除了自定义的排序方法还有两种快捷的方式
1、在已完成的Comparator对象上再调用 reversed()方法依然返回Comparator对象不过是翻转后的从小到大就变成了从大到小
2、对于对象可以直接使用Comparator.comparing(User::getAge,Comparator.naturalOrder()), 这样的快捷构造来指定排序。
第一个就是排序的字段第二个表示自然的排序naturalOrder(从小到大) 还是倒序reverseOrder (从大到小) 因为对象比基本类型占用空间大如果排完序之后再翻转而同时数组长度比较大那么就可能有性能问题所以可以直接指定排序的方向避免不必要的浪费 这一点可以追溯一下这里传入的第二个参数其实就是排序方法的实例 NaturalOrderComparator 比较是 c1.compareTo(c2); 而 ReverseComparator 比较是 c2.compareTo(c1);
那么就比较明显了他不是最终翻转而是比较过程中就已经取反了
因此对象排序优先使用这样的方式去指定排序特别是倒序的时候
高级排序
部分高级排序用法程序设计的非常完善有效好用
空值处理
Stream流处理不会处理空值也就是Null如果原始Stream流里面有空值那么就直接会报空指针异常
如果可能有空值一般需要过滤掉空值之后再排序filter 返回布尔值只保留返回true的数据 list4.stream().filter(p - p.getAge() ! null).sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder())).forEach(p - System.out.print(p ));如果空值还需要处理(比如追加列表最后)一般用单独的数组存放 ListUser emptyList list4.stream().filter(p - p.getAge() null).collect(Collectors.toList());ListUser resList list4.stream().filter(p - p.getAge() ! null).sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder())).collect(Collectors.toList());resList.addAll(emptyList);多字段排序
可能单个字段排序不够需要两次排序甚至多次排序
其实也已经提供了现成的方法,thenComparing,同样返回的还是Comparator对象那么可以继续追加
比如 我的原始数据是 ListUser list4 Lists.newArrayList(User.builder().age(1).score(2).build(), User.builder().age(2).score(2).build(), User.builder().age(2).score(1).build(), User.builder().age(2).score(8).build(), User.builder().age(3).score(8).username(qiushi).build(), User.builder().age(3).score(5).build());而排序方法是
.sorted(Comparator.comparing(User::getAge, Comparator.naturalOrder()).thenComparing(User::getScore, Comparator.naturalOrder()))那么最终结果就是先 age 顺序score顺序
User(usernamenull, age1, score2)
User(usernamenull, age2, score1)
User(usernamenull, age2, score2)
User(usernamenull, age2, score8)
User(usernamenull, age3, score5)
User(usernameqiushi, age3, score8)所以你明白了么 先写到这里后续再来补充欢迎讨论指正biu~
结论速记
1、默认是点名 从小到大排序空值需自己处理
2、可以自定义排序方法使用匿名函数(lambda表达式)快速实现提供快速 转化数值的方法comparingInt 、comparingLong、comparingDouble
3、对象如果需要倒序尽量指定排序方向Comparator.comparing(User::getAge,Comparator.naturalOrder()),比最后来翻转reversed()的性能更好
4、支持多字段排序使用thenComparing 方法依次指定
日常偷图侵删