为了账号安全,请及时绑定邮箱和手机立即绑定

带有过滤条件工作流程的 Java 8 流

带有过滤条件工作流程的 Java 8 流

慕妹3146593 2021-08-06 10:23:28
在带有过滤条件的 Java 8 流中,集合中的每个元素都被传递给过滤器以检查条件。在这里,我正在编写两种不同的过滤条件并给出不同的工作流程。public static void main(String[] args) {    List<String> asList = Arrays.asList("a", "b", "c", "d", "e", "a", "b", "c");    //line 1    asList.stream().map(s -> s).filter(distinctByKey(String::toString)).forEach(System.out::println);    Predicate<String> strPredicate = (a) -> {        System.out.println("inside strPredicate method--");        return a.startsWith("a");    };    //line 2    asList.stream().filter(strPredicate).forEach(System.out::println);}public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {    System.out.println("inside distinctByKey method...");    Set<Object> seen = ConcurrentHashMap.newKeySet();    return t -> seen.add(keyExtractor.apply(t));}在上面的示例代码中,语句第 1 行过滤条件只执行一次,但第 2 行正在为集合输出中的每个元素执行。我认为该distinctByKey方法会为集合中的每个元素执行,但事实并非如此。为什么 ?另外,Set对象引用变量seen是仅执行一次?流量如何运作?
查看完整描述

2 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

distinctByKey是一个 lambda 工厂方法。它正在返回一个Predictate<T>.


所以当你执行时:filter(distinctByKey(String::toString))你实际上是distinctByKey先调用方法,然后返回一个Predicate. 然后为每个元素执行该谓词。只是工厂函数只会执行一次。


移动System.out.println返回的 lambda 内部时,您将获得所需的打印语句:


public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {

    System.out.println("inside distinctByKey method...");

    Set<Object> seen = ConcurrentHashMap.newKeySet();

    return t -> {

        System.out.println("inside distinctByKey.lambda method... ");

        return seen.add(keyExtractor.apply(t));

    };

}


查看完整回答
反对 回复 2021-08-06
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

seen拍摄由lambda表达式和缓存的拉姆达里面,一旦你的回报Predicate-在Predicate::test将与被多次调用同一实例seen


查看完整回答
反对 回复 2021-08-06
  • 2 回答
  • 0 关注
  • 172 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信