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

相当于Java8中Scala的foldLeft

董子平
2023-03-14

在Java8中,Scala伟大的foldLeft的等价物是什么?

我很想知道它是reduce,但是reduce必须返回与它所还原的内容类型相同的内容。

例子:

import java.util.List;

public class Foo {

    // this method works pretty well
    public int sum(List<Integer> numbers) {
        return numbers.stream()
                      .reduce(0, (acc, n) -> (acc + n));
    }

    // this method makes the file not compile
    public String concatenate(List<Character> chars) {
        return chars.stream()
                    .reduce(new StringBuilder(""), (acc, c) -> acc.append(c)).toString();
    }
}

上面代码中的问题是accumulator:newstringbuilder(“”)

因此,有人能给我指出与“foldLeft/修复我的代码”对应的正确方法吗?

共有3个答案

宦树
2023-03-14

您正在寻找的方法是java。util。流动减少,特别是使用三个参数(标识、累加器和二进制函数)的过载。这是Scala的foldLeft的正确等价物。

但是,不允许这样使用Java的reduce,也不允许Scala的foldLeft。使用收集

东云
2023-03-14

更新:

以下是修复代码的初步尝试:

public static String concatenate(List<Character> chars) {
        return chars
                .stream()
                .reduce(new StringBuilder(),
                                StringBuilder::append,
                                StringBuilder::append).toString();
    }

它使用以下减少方法:

<U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

这听起来可能让人困惑,但如果你看一下javadocs,有一个很好的解释可以帮助你快速掌握细节。减少量相当于以下代码:

U result = identity;
for (T element : this stream)
     result = accumulator.apply(result, element)
return result;

有关更深入的解释,请查看此来源。

但这种用法并不正确,因为它违反了reduce的约定,reduce规定累加器应该是一个关联的、无干扰的、无状态的函数,用于将附加元素合并到结果中。换句话说,由于标识是可变的,因此在并行执行的情况下,结果将被破坏。

正如下面的评论所指出的,正确的选择是使用如下减少:

return chars.stream().collect(
     StringBuilder::new, 
     StringBuilder::append, 
     StringBuilder::append).toString();

供应商StringBuilder::new将用于创建可重复使用的容器,这些容器将在以后合并。

柳英资
2023-03-14

在Java8的Stream API中没有等效的foldLe。正如其他人所指出的,减少(标识、累加器、组合器)很接近,但它与fold左不等同,因为它要求生成的类型B与自身结合并具有关联性(换句话说,类似于单数),不是每个类型都有的属性。

对此还有一个增强请求:添加Stream.fold左()终端操作

要了解为什么Read将不起作用,请考虑下面的代码,在这里,您打算从给定的数字开始执行一系列算术运算:

val arithOps = List(('+', 1), ('*', 4), ('-', 2), ('/', 5))
val fun: (Int, (Char, Int)) => Int = {
  case (x, ('+', y)) => x + y
  case (x, ('-', y)) => x - y
  case (x, ('*', y)) => x * y
  case (x, ('/', y)) => x / y
}
val number = 2
arithOps.foldLeft(number)(fun) // ((2 + 1) * 4 - 2) / 5

如果您尝试编写reduce(2,fun,combine),您可以传递什么组合器函数来组合两个数字?将这两个数字相加显然无法解决问题。此外,值2显然不是标识元素。

请注意,任何需要顺序执行的操作都不能用减少来表示。fold左实际上比减少更通用:您可以用fold左来实现减少,但您不能实现fold左减少

 类似资料:
  • 问题内容: 我想知道Scala或其著名的数学库之一(例如Spire)是否具有与Go 函数相同的功能 (来自http://tour.golang.org/#4) 如果没有,那么获得相同功能的最“ Scala”方法是什么? 问题答案: 它是Java 库的一部分:

  • 问题内容: 我的任务是为开源应用程序编写身份验证组件。我们有一个使用的内部身份验证小部件。我有一些例子访问的代码,它使用来办理过户。 我的问题是,是否有to 的端口,或者更好的是,什么基本软件包将使我足够接近以处理任务? 更新 : 简而言之,我想在JAVA中复制的代码: 我认为您的目标是正确的,我认为我最终将使用HttpsURLConnection,然后从响应中选择所需的内容。 问题答案: 省略异

  • 问题内容: 我希望使用来自Node.js的HTTP请求中的信息(即调用远程Web服务并将响应回显到客户端)。 在PHP中,我会使用cURL来做到这一点。Node的最佳做法是什么? 问题答案: 有关完整示例,请参见HTTP模块的文档: https://nodejs.org/api/http.html#http_http_request_options_callback

  • 问题内容: 我正在自学python 2.7。我在使用具有GOTO语句的BATCH方面有一些经验。我该如何在python中做到这一点?例如,假设我想从第5行跳到第18行。 我意识到以前有关于此主题的问题,但是我发现它们没有足够的信息,或者对于我目前的理解而言,在python中的水平太高了。 问题答案: s在计算机科学和编程中普遍受到指责,因为它们会导致非常非结构化的代码。 Python(像当今几乎所

  • 问题内容: 我在Visual Basic中有一个加密的字符串。NET 2008,加密和解密的功能如下: 例如,使用此功能加密的单词“ android”会给我结果“ B3xogi / Qfsc =“ 现在我需要使用相同的密钥“ key12345”从java解密字符串“ B3xogi / Qfsc =“,其结果应为“ android” …任何人都知道该怎么做? 提前致谢。 问题答案: 使用Apache

  • 问题内容: 在Jackson中,您可以通过在类级别进行注释来忽略属性,而不在JSON中的属性不会在Java类中进行序列化/反序列化。如果我们使用GSON,那相当于什么? 问题答案: 您可以使用使用GSON 注释获得类似的效果。 例如 如果与上述类一起使用,则和方法将完全忽略密码字段,因为它没有注释。 (请注意,在这里您还可以获得更细粒度的控制,因为您还可以控制GSON是否对字段进行序列化/反序列化