繁体   English   中英

在java 8中传递供应商而不是函数作为参数

[英]Passing Supplier instead of Function as argument in java 8

我想根据 Person 类中的某些属性过滤掉重复项。 我有一个方法定义如下:

 private static <T> Predicate<T> distinctByKeys(final Function<? super T, ?>... keyExtractors) 
{
  final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();
 
return t -> 
{
  final List<?> keys = Arrays.stream(keyExtractors)
              .map(ke -> ke.apply(t))
              .collect(Collectors.toList());
   
  return seen.putIfAbsent(keys, Boolean.TRUE) == null;
  };
 }

对上述方法的调用是这样的:

    List<Person> distinctPersons = list.stream()
      .filter(distinctByKeys(Person::getFirstName, Person::getLastName))
      .collect(Collectors.toList());

在方法定义中,我可以看到参数可以是函数实现,但在上面的代码中传递的参数是供应商类型(因为它们返回结果并且不接受任何参数。但这工作正常。任何人都可以解释它是如何工作的。

如果使用Type::method使用方法引用,其中method是非静态的,则对象有一个显式参数来调用该方法。 在您的情况下, Person::getFirstName类似于(Person p) -> p.getFirstName()

上面代码中传递的参数是Supplier类型(因为它们返回结果而不采用任何 arg 。但这很好用。任何人都可以解释它是如何工作的。

在以下代码中:

.filter(distinctByKeys(Person::getFirstName, Person::getLastName))

方法引用Person::getFirstNamePerson::getLastName不是Supplier类型,它们是Funtion ,因为它们确实需要Person类型的参数才能返回一个人的名字姓氏

在第一个示例中,我只是将 distinctByKeys 和 forSupplier 方法分配给 Function 接口。 然后我只是通过给定参数应用(执行)方法和应用方法。

正如您从第二个示例中看到的那样,也可以使用供应商。 最后一个例子是你的。 但我有一个问题。

distinctByKeys 方法中的映射实例化有点可疑。 我可以想象当每个人都被过滤器方法调用时,map 被实例化了,所以这意味着它每次都会返回 true,因为 map 是空的,并且 map 中没有被 seen.putIfAbsent(keys, Boolean. TRUE) 方法调用。

private static Predicate functionExample() {
    Function<Function[], Predicate> f = Scratch::distinctByKeys;
    Function<Supplier[], Predicate> f2 = Scratch::forSupplier;
    f2.apply(new Supplier[0]);
    return f.apply(new Function[0]);
}


private static <T> Predicate<T> forSupplier(final Supplier<? super T>... suppliers) {
    final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();

    return t ->
    {
        final List<?> keys = Arrays.stream(suppliers)
                .map(Supplier::get)
                .collect(Collectors.toList());

        return seen.putIfAbsent(keys, Boolean.TRUE) == null;
    };
}

private static <T> Predicate<T> distinctByKeys(final Function<? super T, ?>... keyFields)
{
    final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();

    return t ->
    {
        final List<?> keys = Arrays.stream(keyFields)
                .map(ke -> ke.apply(t))
                .collect(Collectors.toList());

        return seen.putIfAbsent(keys, Boolean.TRUE) == null;
    };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM