23

私たち全員が使用しなければならなかったこの退屈なコードがあるとしましょう:

ArrayList<Long> ids = new ArrayList<Long>();
for (MyObj obj : myList){
    ids.add(obj.getId());
}

Java 8 に切り替えた後、私の IDE は、このコードを に置き換えることができると通知しcollect call、自動生成します:

ArrayList<Long> ids = myList.stream().map(MyObj::getId).collect(Collectors.toList());

ただし、このエラーが表示されます:

Steam の collect(java.util.stream.Collector) は適用できません: (java.util.stream.Collector, capture, java.util.List>)

パラメータをキャストしようとしましたが、未定義のAandRが返され、IDE はそれ以上の提案をしません。

このシナリオでどのように使用できるか興味がありますcollect callが、適切にガイドできる情報が見つかりませんでした. 誰でも光を当てることができますか?

4

2 に答える 2

47

問題はCollectors.toList、当然のことながら、 が を返すことList<T>です。ではありませんArrayList

List<Long> ids = remove.stream()
        .map(MyObj::getId)
        .collect(Collectors.toList());

にプログラムしますinterface

ドキュメントから:

Collector入力要素を新しい に蓄積する を 返しますList返される の型、可変性、直列化可能性、またはスレッド セーフ性についての保証Listはありません。返されたリストをさらに制御する必要がある場合は、 を使用します toCollection(Supplier)

List私の強調点-返されたものが特定のクラスであることは言うまでもなく、変更可能であると想定することさえできません。あなたがしたい場合ArrayList

ArrayList<Long> ids = remove.stream()
        .map(MyObj::getId)
        .collect(Collectors.toCollection(ArrayList::new));

import staticまた、 Java 8 StreamAPIで使用するのが通例であるため、以下を追加することに注意してください。

import static java.util.stream.Collectors.toCollection;

(私は starredimport staticが嫌いです。それは名前空間を汚染し、混乱を招くだけです。しかし、selectiveimport staticは、特に Java 8 ユーティリティ クラスを使用すると、冗長なコードを大幅に削減できます)

次のようになります。

ArrayList<Long> ids = remove.stream()
        .map(MyObj::getId)
        .collect(toCollection(ArrayList::new));
于 2014-11-13T09:29:32.923 に答える
2

私は多くのコレクター ブロックを使用して、空の配列を作成し、ループを使用してそれを埋めるため、同じ行を再度記述しないように独自のユーティリティ クラスが必要であると判断しました。これは次のとおりです。

public class Collections {

    public static <T, O> List<T> collect(Set<O> items, Function<? super O, ? extends T> mapper) {

    return items.stream().map(mapper).collect(Collectors.toCollection(ArrayList::new));
}

}

そして、このように使用します

List<Product> prods = Collections.collect(basket.getOrderItems(), OrderItem::getProduct);

またはこのように

List<Long> prods = Collections.collect(basket.getOrderItems(), (item)->item.getProduct().getId());

はるかに読みやすいように見えるかもしれませんが、この種のシナリオではストリームが少し遅くなるようです。

于 2015-04-25T04:01:24.587 に答える