Java8 Stream 流一边 filter 过滤一边 map 映射?? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
easterfan
V2EX    问与答

Java8 Stream 流一边 filter 过滤一边 map 映射??

  •  
  •   easterfan 2020 年 11 月 20 日 2949 次点击
    这是一个创建于 1878 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一时 stream 一时爽,用习惯了以后,突然想到对于流,能否实现过滤和 map 同时进行的操作,比如一个场景:

    // 如果元素是奇数,就 + 1,如果元素是偶数,就 +2,期望一顿流式操作后,输出一个新的 List:{2,4,4,6,6} List<Integer> input = Arrays.asList(1, 2, 3, 4, 5); inputList.stream() .filter(p -> xxx) .map(p -> xxx) .collect(Collectors.toList()); 

    现在最高频用到的 filter 通常只有一个条件,是从原来的 List 中过滤出满足条件的元素,然后对这些元素进行 map 操作,

    如果对一个集合,有两种过滤条件 A 和 过滤条件 B,满足过滤条件 A 就对元素进行 mapA 操作,满足过滤条件 B,就对元素进行 mapB 操作,最后元素都按照不同的 map 方式映射完了,再放到同一个集合里~~

    初用 stream,有大佬这样操作过嘛~~

    14 条回复    2020-12-08 14:43:30 +08:00
    chanchan
        1
    chanchan  
       2020 年 11 月 20 日   2
    peek 了解一下
    wowo243
        2
    wowo243  
       2020 年 11 月 20 日
    partitioningBy()?
    ye2moe
        3
    ye2moe  
       2020 年 11 月 20 日
    直接的话是做不到的,可以搞两个流操作再合起来就好了。
    easterfan
        4
    easterfan  
    OP
       2020 年 11 月 20 日
    @wowo243
    @ye2moe
    ```java
    Map<Boolean, List<Integer>> partitiOnMap= Stream.of(1, 2, 3, 4, 5).collect(Collectors.partitioningBy(p -> p / 2 == 0));

    Stream<Integer> evenStream = partitionMap.get(true).stream().map(p -> p + 2);
    Stream<Integer> oddStream = partitionMap.get(false).stream().map(p -> p + 1);
    Stream.concat(evenStream, oddStream);
    ```
    分组成两个流,然后再合并,合并后的流和原来的流元素顺序不一样了~~
    anzu
        5
    anzu  
       2020 年 11 月 20 日   1
    为什么要 filter,奇偶不是二选一吗。如果判断条件复杂,要么 map 里面多写点代码,要么用 for
    input.stream().map(p -> p % 2 == 0 ? p + 2 : p + 1).collect(Collectors.toList())
    easterfan
        6
    easterfan  
    OP
       2020 年 11 月 20 日
    @anzu
    感谢大佬!解决了我的问题,用 map 前总是很习惯的 filter 一下,有了思维定式,用你的思路,把判断逻辑写在 map 里,对一个元素 map 前先做一次判断,然后执行对应的 map,已经达到了我在找的一边 filter,一边 map 的想法,感谢!

    ```java
    Stream.of(1,2,3,4,5)
    .map(p -> {if(isFilterA) mapA(); if (isFilterB) mapB(); if (isFilterC) mapC();})
    .collect(Collectors.toList());
    ```
    (原来的固定思维的想法~:)
    https://imgur.com/7sn8euR
    jimmyismagic
        7
    jimmyismagic  
       2020 年 11 月 20 日
    @easterfan filter 概念要搞清楚啊,没事干嘛搞 filter
    optional
        8
    optional  
       2020 年 11 月 20 日 via iPhone
    rx 欢迎你
    easterfan
        9
    easterfan  
    OP
       2020 年 11 月 20 日
    @jimmyismagic 母鸡啊~写顺手了,map 前必 filter~~Q
    easterfan
        10
    easterfan  
    OP
       2020 年 11 月 20 日
    @optional
    敢问 rx 是?这 id 很 6
    jimmyismagic
        11
    jimmyismagic  
       2020 年 11 月 20 日   1
    @easterfan rxJava,另外还有 project reactor,都是响应式编程,但其中也使用了 streams 里的一些概念
    itechify
        12
    itechify  
    PRO
       2020 年 11 月 20 日 via Android   1
    在 map 里面直接判断 A 或 B 条件分开转换就行了吧

    借楼,题外话,最近密的 stream 的另一个 API,Collectors.mapping,真是节省了不少代码逻辑,主要用于 group 分组后的 value 集合再 map

    ttps://stackoverflow.com/questions/52281724/java-streams-group-list-entries-based-on-a-property-but-collect-a-property-of-ob

    知道这个 API 的大佬请忽略
    zch693922
        13
    zch693922  
       2020 年 11 月 21 日   1
    按一楼的 peek 一下就可以了
    list.stream().peek(item -> {
    if (xxxxx) { do something}
    if (xxxx) {item.setXXX}
    })
    easterfan
        14
    easterfan  
    OP
       2020 年 12 月 8 日
    @zch693922
    @chanchan

    感谢回答!最近试了 map 和 peek 两种实现方式,实践后发现可能 map 更适用这种情况,具体原因是使用 peek 后续再进行终端操作(比如 collect/count )时,会出现报错:`java.lang.UnsupportedOperationException`, peek 可能只适合调试的场景,个人解释能力有限,感兴趣的话这篇文章举的例子挺好的:

    https://stackoverflow.com/questions/44370676/java-8-peek-vs-map
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2786 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 12:23 PVG 20:23 LAX 04:23 JFK 07:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86