当前位置: 首页 > 知识库问答 >
问题:

Java 8中谓词如何维护状态

鲁乐
2023-03-14
public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
    Map<Object,Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

BigDecimal totalShare = orders.stream()
    .filter(distinctByKey(o -> o.getCompany().getId()))
    .map(Order::getShare)
    .reduce(BigDecimal.ZERO, BigDecimal::add);

我的问题是每次调用distinctByKey并产生新的ConcurrentHashMap。如何使用新的ConcurrentHashMap<>()维护状态;?

共有1个答案

葛修筠
2023-03-14

由于这是一个捕获λ,因此在每次调用DistinctByKey时,实际上都会返回一个新的谓词实例;但这将发生在整个流,而不是每个单独的元素。

如果您愿意使用以下内容运行示例:

djdk.internal.lambda.dumpProxyClasses=/your/path/here

DistinctByKey的每次调用都将生成一个不同的实例,但该实例将被重用用于流的每个元素。如果运行这个示例,情况可能会更加明显:

 public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
    Map<Object,Boolean> seen = new ConcurrentHashMap<>();
    Predicate<T> predicate =  t -> {
        Object obj = keyExtractor.apply(t);
        System.out.println("stream element : " + obj);
        return seen.putIfAbsent(obj, Boolean.TRUE) == null;
    };

    System.out.println("Predicate with hash :" + predicate.hashCode());
    return predicate;
}

@Getter
@AllArgsConstructor
static class User {
    private final String name;
}

public static void main(String[] args) {
    Stream.of(new User("a"), new User("b"))
          .filter(distinctByKey(User::getName))
          .collect(Collectors.toList());

}

这将输出:

Predicate with hash :1259475182
stream element : a
stream element : b

流的两个元素都有一个谓词

Stream.of(new User("a"), new User("b"))
      .filter(distinctByKey(User::getName))
      .filter(distinctByKey(User::getName))
      .collect(Collectors.toList());
Predicate with hash :1259475182
Predicate with hash :1072591677
stream element : a
stream element : a
stream element : b
stream element : b
 类似资料:
  • 我对EJB有点陌生。我已经理解了HTTPSession是如何维护的(所有cookie funda)。互联网上所有的资源都写着“有状态会话Bean维护会话(记住客户机)”,但我找不到答案

  • 问题内容: 我有一个清单,我想分成几个小清单。 说出所有包含“ aaa”的项目,所有包含“ bbb”的项目以及更多谓词。 我该如何使用java8? 我看到了这篇文章,但只拆分为2个列表。 我看到了这篇文章,但是在Java 8之前已经很老了。 问题答案: 就@RealSkeptic中解释的那样,注释只能返回两个结果:true和false。这意味着您将只能将数据分为两组。 您需要的是某种可以让您确定应

  • 我试图创建一个从最终用户抽象谓词使用的类。 我的应用程序使用了番石榴重试扩展,效果很好。 我可以很容易地用谓词调用它,它会轮询,直到谓词返回false。 现在,也许我误解了谓词,但我正在尝试创建一个类来抽象它们。 我想这样称呼它 所以我写了如下PollCondition类。 但是MyPoller。poll()调用无法编译-未声明结果。 知道吗?

  • Google Guava有一个谓词,它总是返回。Java8的有类似的东西吗?我知道我可以使用,但我需要一些预先制作的东西,类似于。

  • 有两个具有相同结构的地图,即map1和map2,其结构为

  • 这是我的家长课 然后我创建了一个列表 然后我向objList添加了许多父对象。 现在我想根据类中字段的值过滤这些对象。但是我只会动态地得到字段名。我想为此使用流。 这里getAttrib2()有所不同。它可以是getAttrib1()或getAttrib3()。 所以我需要动态函数调用。我们能用谓词实现它吗。不幸的是,我对谓词对象一无所知。请详细解释你的答案,里面有所有的概念。