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

如何使用Java 8中的方法引用进行地图合并?

戚兴思
2023-03-14

我有以下两种调用集合操作的形式,都返回相同的结果,但我仍然不能完全依赖于方法引用,需要一个lambda。

<R> R collect(Supplier<R> supplier,
          BiConsumer<R,? super T> accumulator,
          BiConsumer<R,R> combiner)

为此,考虑以下由100个随机数组成的流

List<Double> dataList = new Random().doubles().limit(100).boxed()
            .collect(Collectors.toList());

1) 以下示例使用纯lambda

Map<Boolean, Integer> partition = dataList.stream()
            .collect(() -> new ConcurrentHashMap<Boolean, Integer>(),
(map, x) ->
{
    map.merge(x < 0.5 ? Boolean.TRUE : Boolean.FALSE, 1, Integer::sum);
}, (map, map2) ->
{
    map2.putAll(map);
});

2) 以下尝试使用方法引用,但第二个参数仍然需要lambda

Map<Boolean, Integer> partition2 = dataList.stream()
            .collect(ConcurrentHashMap<Boolean, Integer>::new, 
(map, x) ->
{
    map.merge(x < 0.5 ? Boolean.TRUE : Boolean.FALSE, 1, Integer::sum);
}, Map::putAll);

在本例中,如何重写java 8中collect方法的第二个参数以使用方法引用而不是lambda?

System.out.println(partition.toString());
System.out.println(partition2.toString());
{false=55, true=45}
{false=55, true=45}

共有1个答案

路和悌
2023-03-14

如果您有一个现有的方法可以精确地执行预期的操作,那么方法引用是一个方便的工具。如果需要修改或附加操作,则方法引用没有特殊的语法来支持这一点,除非您将lambda表达式视为该语法。

当然,您可以在类中创建一个新方法来完成所需的任务,并创建对它的方法引用,当代码的复杂性增加时,这是正确的方法,因为这样,它将得到一个有意义的名称并成为可测试的。但对于简单的代码段,可以使用lambda表达式,这只是用于相同结果的更简单语法。从技术上讲,这没有什么区别,只是保存lambda表达式体的编译器生成的方法将被标记为“合成”。

在您的示例中,您甚至不能使用Map::putAll作为合并函数,因为这会覆盖第一个map的所有现有映射,而不是合并值。

正确的实现看起来像

Map<Boolean, Integer> partition2 = dataList.stream()
    .collect(HashMap::new, 
             (map, x) -> map.merge(x < 0.5, 1, Integer::sum),
             (m1, m2) -> m2.forEach((k, v) -> m1.merge(k, v, Integer::sum)));

但您不需要自己实现它。Collector类中已经提供了适当的内置收集器:

Map<Boolean, Long> partition2 = dataList.stream()
    .collect(Collectors.partitioningBy(x -> x < 0.5, Collectors.counting()));
 类似资料:
  • 本文向大家介绍使用Java8中的方法引用来引用实例方法,包括了使用Java8中的方法引用来引用实例方法的使用技巧和注意事项,需要的朋友参考一下 Java中的Lambda表达式使您可以将功能作为参数传递给方法。您也可以使用lambda表达式调用现有方法。 方法引用是简单,易于阅读的lambda表达式,可通过lambda表达式中的名称来调用/引用和现有方法。 语法 以下是在Java中引用实例方法的语法

  • 主要内容:1 Java8 方法引用的介绍,2 Java8 方法引用的分类,3 Java8 方法引用:引用静态方法,4 Java8 方法引用:引用实例方法,5 Java8 方法引用:引用构造方法1 Java8 方法引用的介绍 Java提供了一个新功能,称为Java 8中的方法引用。方法引用用于引用功能接口的方法。它是lambda表达式的紧凑和简单形式。每次使用lambda表达式仅引用方法时,都可以将lambda表达式替换为方法引用。在本教程中,我们将详细解释方法参考概念。 2 Java8 方法引用

  • 我正在通过一个例子,它从与方法引用相关的当前目录中提取一个隐藏文件数组,如下所述 使用匿名内部类实现 使用方法参考实现 我的问题是接口只有一个抽象方法(),而实现accept-method-using-method-reference在类中使用的有效性如何。我了解到,只有当参数与抽象方法匹配时,我们才能应用方法引用,但是这里method有一个类型的参数,但是没有参数。你能解释一下它的有效性吗。

  • 本文向大家介绍使用Java8中的方法引用来引用构造函数,包括了使用Java8中的方法引用来引用构造函数的使用技巧和注意事项,需要的朋友参考一下 Java中的Lambda表达式使您可以将功能作为参数传递给方法。您也可以使用lambda表达式调用现有方法。 方法引用是简单,易于阅读的lambda表达式,可通过lambda表达式来调用/引用以及现有方法的名称。除了实例和静态方法,您还可以使用new关键字

  • 我一直在研究这三个网站,了解如何使用log4j2创建地图查找(或任何其他查找): http://logging.apache.org/log4j/2.x/manual/extending.html#Lookups http://logging.apache.org/log4j/2.x/manual/lookups.html http://logging.apache.org/log4j/2.x/m

  • 我对方法引用在Java8中是如何工作的有些困惑。我编写了下面的代码段用于过滤文件夹中的隐藏文件。他们正在产生正确的结果。我不理解->listFiles方法的方法签名是如何在这个代码段的选项2中工作的。 这是我在Java8文档中发现的