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

Java 8 Lambdas:将流映射为整数类型,然后调用sum()不会编译

阎京
2023-03-14

我正在玩Java8 lambda表达式。作为一个例子,我试图总结一个列表中包含的年龄:

import java.util.Arrays;
import java.util.List;

public class Person {
    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
        Integer sumOfAges = persons.stream().map(Person::getAge).sum();
        System.out.println("summedUpAges: " + sumOfAges);
    }

    private final String name;
    private final Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
}

当我试图用下面的java编译器编译这段代码时:

openjdk version "1.8.0-ea"
OpenJDK Runtime Environment (build 1.8.0-ea-lambda-night
OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode)

我得到以下编译错误:

java: cannot find symbol
  symbol:   method sum()
  location: interface java.util.stream.Stream<java.lang.Integer>

但是,如果我将 getAge() 方法的返回值从 Integer 更改为 int,我会得到预期的结果。但有时不可能或不希望动态更改签名。当 getAge() 返回 Integer 类型时,有没有办法使它工作?

丹尼尔,先谢谢你了

共有3个答案

谯德佑
2023-03-14

添加河口。io答案,我更喜欢lambda表达式而不是方法引用。

persons.stream().mapToInt(x->x.getAge()).sum();
云季同
2023-03-14

他们没有改变方法,它们都可以在as map()是返回Stream的广义方法的情况下使用,并且他们将int、long、Double Stream分离为单独的方法,例如mapToInt()、mapToLong()和mapToDouble()。

是的,你可以使用reduce()方法

reduce(T恒等式,二进制运算符)

使用关联累加函数对此流的元素执行缩减,并返回描述缩减值的可选值(如果有)。

reduce()如何工作:假设我们有一个int数组流,并应用reduce函数

减少(0,(l,r)-

在1、2、3、4和5等整数列表中,种子0加1,结果(1)存储为累加值,该值除了用作流中的下一个数字(1 ^ 2)之外,还用作左边的值。结果(3)存储为累加值,并用于下一次加法(3 ^ 3)。结果(6)被存储并用于下一次加法(6 ^ 4),并且该结果被用于最终加法(10 ^ 5),产生最终结果15。

因此,您的示例如下所示:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class Person {

    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
        Stream<Integer> stream = persons.stream().map(x -> x.getAge());
        int sum = stream.reduce(0, (l, r) -> l + r);
        System.out.println(sum);

    }

    private final String name;
    private final Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
}
微生宝
2023-03-14

我认为他们正在改变方法

IntStream map(ToIntFunction<? super T> mapper)

IntStream mapToInt(ToIntFunction<? super T> mapper)

然后你的

persons.stream().mapToInt(Person::getAge).sum()

无论< code>getAge()返回< code>int还是< code>Integer,都将始终有效。

查看此线程:http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001480.html

顺便说一句,您可以将您的问题发布到lambda dev邮件列表,他们希望听到真实世界的体验。

 类似资料:
  • 有一个SQL数据库包含此过程 t_字段类型的定义如下: 我正在使用JDBC调用该过程,我知道我需要一个连接和一个callStmt,但我不确定如何处理t_字段参数映射。有什么建议吗?

  • 什么是实现历史地图的最佳方式,其中值侧是地图或集合? 我需要类似于以下内容的数据结构,我可以使用特定id存储某些数据的多个版本: 或者可能有两张地图: (原子性和序列化性能是我主要关心的问题)方法似乎不适用于标准映射/集实现。

  • 在java 8中创建新代码后,我想清除声纳问题。 我的代码: 声纳说: Lambda应该替换为方法引用。方法/构造函数引用比使用lambda更紧凑和可读性,因此是首选。同样,空检查可以替换为对Object::isNull和Object::nonNull方法的引用。 我想要更改映射(arg-

  • 问题内容: 我在ES 1.3.4和JDBC For MySql 1.3.4.4的本地实例上拥有River 这条河工作得很好,并在ES中导入数据。我遇到的问题是我的一个字段是文本字段,并且其中包含空格。例如“实时计算器”。ES将其索引为“实时”,“时间”和“计算器”,而不是“实时计算器”。 所以我正在使用下面提到的JSON创建映射: 和命令: 但是我得到以下提到的错误: 当我尝试使用下面提到的命令查

  • 我在解决泛型问题时遇到了一些麻烦。我有一个“猫”对象列表和一个“狗”对象列表,我需要将它们传递到同一个方法中。该方法的返回类型是一个“字符串”和“动物列表”的映射,我试图找出一种方法来将带有动物列表的映射转换为带有猫或狗列表的映射。 这工作很好,如果我有一个单独的方法猫和狗,但我正在寻找一个更灵活的解决方案。 标题中出现错误的行: 注意:这是一个简化的例子,我必须能够使用地图中的列表作为“猫”或“

  • 类型映射 web3j中使用的原生Java到ABI类型映射如下: boolean -> bool BigInteger -> uint/int byte[] -> bytes String -> string and address types List<> -> dynamic/static array BigInteger类型必须用于数字类型,因为Ethereum以太坊中的数字类型是256位整数