2013-03-21 5 views
13

Java 8ラムダ式で遊んでいました。一例として、私は、リストに含まれている年齢者を総括してみました:Java 8 Lambdas:ストリームを整数型にマッピングしてからsum()を呼び出すとコンパイルされません

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型を返すときにこれを動作させる方法はありますか?事前に

おかげで、 ダニエル

+0

'reduce()'も正しく動作するはずです - 'map(Person :: getAge).reduce(0、Integer :: sum)' – ZhongYu

答えて

16

私は、彼らがあなたの

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

意志ALWが、その後

IntStream mapToInt(ToIntFunction<? super T> mapper) 

に方法

IntStream map(ToIntFunction<? super T> mapper) 

を変更していると思いますgetAge()intまたはIntegerを返すかどうかを確認します。

このスレッドを参照してください:ところであなたは、ラムダ-devメーリングリストにご質問を投稿することができhttp://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001480.html

、彼らは現実世界の経験を聞きたいと思います。 マップ()としてストリームを返す一般的な方法であり、ここで彼らは方法を変更しない

2

は、それらの両方が利用可能であり、それらはmapToIntようとして別の方法にint型、長い、二重ストリームを分離しています()、mapToLong()とmapToDouble()。

はい、あなたは減らす()メソッドを使用することができます

削減(Tアイデンティティ、BinaryOperator < T>アキュムレータ)

は、連想蓄積機能を使って、このストリームの要素の削減を行います減少した値があればそれを記述するOptionalを返します。

どのように(削減)がに動作します:、我々はint配列の流れを持っているし、我々はそのような1、2、3、4、および5などの整数のリストで、機能

reduce(0, (l, r) -> l + r)

を減らす適用すると仮定しますシード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; 
    } 
} 
0

bayou.ioの回答を追加するには、メソッド参照の代わりにラムダ式を使用することをお勧めします。

persons.stream().mapToInt(x->x.getAge()).sum(); 
関連する問題