32 | 加餐2:带你吃透课程中Java 8的那些重要知识点(二)
32 | 加餐2:带你吃透课程中Java 8的那些重要知识点(二)
讲述:王少泽
时长14:28大小13.24M
Stream 操作详解
创建流
filter
map
flatMap
sorted
distinct
skip & limit
collect
groupBy
partitionBy
重点回顾
思考与讨论
赞 24
提建议
精选留言(26)
- 海拉鲁置顶2020-03-17为了写作业又去翻了《Java 8 实战》,测试终于通过了 public class MostPopularCollector implements Collector<Object, // 收集String流 Map<Object, Integer>, // 累加器是一个Map,key为字符,value为出现的次数 Optional> // 返回的是出现次数最多的字符 { /** * 返回一个在调用时创建的累加器 * @return */ public Supplier<Map<Object, Integer>> supplier() { return () -> new HashMap<>(); } /** * 定义收集流中数据逻辑 * @return */ public BiConsumer<Map<Object, Integer>, Object> accumulator() { return (Map<Object, Integer> acc, Object chart) -> acc.compute(chart, (key, val) -> val == null ? 1 : val + 1); // 如果当前字符未统计则统计为1,否则+1 } /** * 处理并行操作,其实就是将两个map合成一个,把value加起来 * @return */ public BinaryOperator<Map<Object, Integer>> combiner() { return (Map<Object, Integer> m1, Map<Object, Integer> m2) -> { Map<Object, Integer> all = new HashMap<>(m1); m2.forEach((chart, count) -> all.merge(chart, count, Integer::sum)); return all; }; } public Function<Map<Object, Integer>, Optional> finisher() { return (Map<Object, Integer> acc) -> Optional.ofNullable(acc.entrySet() .stream() .max(Map.Entry.comparingByValue()) .get().getKey()); } public Set<Characteristics> characteristics() { return Collections.unmodifiableSet(EnumSet.of(Characteristics.CONCURRENT)); } }展开
作者回复: 👍🏻
共 2 条评论11 - Wiggle Wiggle置顶2020-03-17Stream API 有个 peek 方法可以接收一个 consumer 来打印数据,可以接在任意 transformation 操作后面查看数据
作者回复: 是的,这是一种方法,此外IDEA已经增加了非常方便的Stream调试功能,可以参考https://www.jetbrains.com/help/idea/analyze-java-stream-operations.html
8 - 汝林外史置顶2020-03-20private List<Map> getNoRoomList(List<Map> inspectRooms, List<Map> items) { boolean flag = false; List<Map> noInspectRoom = new ArrayList<>(); for (Map item: items) { for (Map inspectRoom: inspectRooms) { if (inspectRoom.get("project").equals(item.get("checkItem"))) { flag = true; break; } } if (!flag) { noInspectRoom.add(item); }else { flag = false; } } return noInspectRoom; } 我直接贴我写的处理代码吧,应该可以理解我的想法,这测试用例还真不好写。展开
作者回复: private static List<Map> getNoRoomList(List<Map> inspectRooms, List<Map> items) { return items.stream().filter(item->inspectRooms.stream().noneMatch(inspectRoom->inspectRoom.get("project").equals(item.get("checkItem")))) .collect(Collectors.toList()); }
4 - 陈天柱2020-03-20老师把stream的常用api与sql操作联系起来,简直是太“亲民”了!9
- Darren2020-03-17以前真没有特意去关注收集器,看了做了,参考了2片文章: https://www.cnblogs.com/yw0219/p/9589124.html https://my.oschina.net/piorcn/blog/424375 最终搞定,请老师指点 https://github.com/y645194203/geektime-java-100/blob/master/MostPopularCollector.java展开
作者回复: 非常好
8 - QQ怪2020-04-12Idea 在debug模式有个Trace Current Stream Chain功能,可以很好的查看数据变化6
- pedro2020-03-17我目前想到的数据观察的方式比较原始,一种是通过log打印,一种是debug。但我肯定这都不是啥好办法,希望老师告知解放生产力的方法。
作者回复: IDEA已经增加了非常方便的Stream调试功能,可以参考https://www.jetbrains.com/help/idea/analyze-java-stream-operations.html
6 - Demon.Lee2020-04-24每天晚上回去敲一点,花了好几个晚上,终于把这两节中的所有代码运行了一遍,只不过似懂非懂,还要继续练习。已经开始在工作中运用一些简单的了,读完这篇文章可能只需要20分钟,但把所有代码都练习一遍,就不是20分钟的事了,要持续学习才行。💪🏽
作者回复: 还是需要自己想案例实际写一下代码
共 2 条评论4 - 👽2020-05-20个人认为,客户端不安全的主要原因是,计算机网络协议。 网络环境中一切都是不可预知,切不安全的。 无法保证你发出去的数据,就是服务器要的数据;也无法保证你发的数据顺序是1,2,3服务器收到的就是1,2,3.有可能服务器收到的是【3,2,1】 【 2,1,3】 【 3,1,2】,甚至有可能【111】或者压根收不到。 在网络中,传输数据的方式,方式是广播,无条件转发,就是任何人都有可能收到,所以必要的就是加密。防止对方知道。 任何人都能收到,任何人也都有权力继续转发,谁都不敢保证,转发的时候会不会给你增加些不安全的信息。这也就是服务端需要校验。展开2
- 密码1234562020-03-28我感觉,比较重要的是,function,optional,consumer,supplier,predicate接口。在stream的学习中,通过单词猜用法。2
- Geek_3b10962020-03-27实用!2
- 汝林外史2020-03-19List<Map> l1,List<Map> l2,两个list,l1中有四个map,其中有key分别为1、2、3、4的四个字段,l2有两个map,其中有key分别为1,2的l1中一样的字段,怎么筛选最终得到一个list,只有key为3、4对应的两个map?写的比较乱,还请老师见谅,我想了下没想出来,最后for循环做的。
作者回复: 把测试用例帖一下,不太明白l1和l2是啥。。。
2 - 初见2020-03-18现在在生产实践用用了很多stream,看了文稿以后,发现自己在有些使用上串联的不够深入,等有时间针对那些操作进行深入的的串联2
- insight2020-03-18//各种转换,后面注释代表了输出结果 System.out.println(IntStream.of(1, 2).toArray().getClass()); //class [I System.out.println(Stream.of(1, 2).mapToInt(Integer::intValue).toArray().getClass()); //class [I System.out.println(IntStream.of(1, 2).boxed().toArray().getClass()); //class [Ljava.lang.Object; System.out.println(IntStream.of(1, 2).asDoubleStream().toArray().getClass()); //class [D System.out.println(IntStream.of(1, 2).asLongStream().toArray().getClass()); //class [J 老师,这一段代码的输出结果为什么是这样的呀?没看懂,求指教!展开
作者回复: 看一下toArray的返回类型对比一下输出就知道了
2 - 鲁鸣2020-09-27发现使用的时候,经常会不知道到底该传入一个什么样子的函数或者lamda表达式1
- 鲁鸣2020-09-27在实际中,发现distinct需要根据元素类型的属性进行判断,这个时候就需要用别的方式了
作者回复: https://stackoverflow.com/questions/23699371/java-8-distinct-by-property/27872852#27872852
1 - 大胖子呀、2020-05-20工作中遇到一个需求,计算运费:先从运费集合中找出同一个客户的数据,然后类似于累加数量(还有很多其他的逻辑)计算出运费(因为相同的客户数量超过一定数值会有优惠)。最后把计算出来的运费数据插入到数据库里。 我的做法是:以第一条数据的客户为基准,循环找出相同客户的数据,保存到一个新的集合中,同时从原数据集合里移除这条数据,最后计算出新集合里的运费就可以了。 感觉这种需求的话,好像就没办法用老师介绍的流方法来遍历计算了,因为不能删除数据,不知道我认为的是不是对的。 另外就我的实现来说,会不会出现问题?有没有更好的解决方案?展开
作者回复: 按照客户直接进行分组聚合不是更简单
共 3 条评论1 - 203。2020-05-12老师 我这里有个问题 关于Stream的,业务需求里需要按某几个字段去重(acctId,billingCycleId,prodInstId,offerId) 我这里想到了遍历集合areaDatas 后用contains方法判断 重写AcctItemYzfBean实体类的equals方法实现, 请问有没有更好的方法? 代码如下 List<AcctItemYzfBean> newList = new CopyOnWriteArrayList<>(); //循环过滤、增强翼支付数据 Optional.ofNullable(areaDatas)//集合判空 .orElse(new ArrayList<>()) .stream()//转化为流 便于下面过滤和增强数据 .filter(Objects::nonNull)//元素判空 .filter(yzfBean -> this.judgeIfOfferId(yzfBean))//判断销售品ID是否相同 .filter(yzfBean -> this.enhanceYzfBean(yzfBean))//增强过滤accNbr和acctId .filter(yzfBean -> this.judgeIfArrears(yzfBean))//判断是否不欠费 .filter(yzfBean -> this.judgeIfCancel(yzfBean))//判断是否销账金额大于0 .filter(yzfBean -> this.judgeIfReturn(yzfBean))//判断是否上月未返还 .forEach(yzfBean -> { //去重 重写AcctItemYzfBean.equals方法 if(!newList.contains(yzfBean)) { //增强latnName yzfBean.setLatnName(commonRegionMap.get(yzfBean.getRegionId())); //增强areaCode yzfBean.setAreaCode(areaCode); //数据封装 newList.add(yzfBean); } }); 重写的equals方法 @Override public boolean equals(Object yzfBeanObj) { if(yzfBeanObj instanceof AcctItemYzfBean) { AcctItemYzfBean yzfBean = (AcctItemYzfBean) yzfBeanObj; if(Tools.isEmpty(yzfBean.getAcctId(), yzfBean.getBillingCycleId(), yzfBean.getProdInstId(), yzfBean.getOfferId())) { return false; } if(yzfBean.getAcctId().equals(this.acctId) && yzfBean.getBillingCycleId().equals(this.billingCycleId) && yzfBean.getProdInstId().equals(this.prodInstId) && yzfBean.getOfferId().equals(this.offerId)) { return true; } } return super.equals(yzfBeanObj); }展开
作者回复: 比如下面的类,id1和id2重复认为是重复的,id3不需要考虑 @Data @Builder @NoArgsConstructor @AllArgsConstructor static class Test { private String id1; private String id2; @EqualsAndHashCode.Exclude private String id3; } 通过Set去重或者通过distinct去重即可: List<Test> list = new ArrayList<>(); list.add(new Test("a","b","c")); list.add(new Test("a","b","d")); System.out.println(list.stream().collect(Collectors.toSet())); System.out.println(list.stream().distinct().collect(Collectors.toList()));
1 - 请叫我和尚2020-04-01这个文章算是我读起来最吃力的一篇了,哈哈哈,多读读,一时间肯定不能消化1
- 阿怪2020-03-25每天上下班阅读,收获满满
作者回复: 觉得好可以多分享
1