State of the Lambda:Libraries Edition を読んでいて、1つの声明に驚いています:
セクションStreamsの下には、次のものがあります。
_List<Shape> blue = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.collect(Collectors.toList());
_
文書にはshapes
が実際には何であるかは記載されておらず、それが問題になるかどうかはわかりません。
私を混乱させるのは次のとおりです。このコードブロックはどのような具体的なList
を返しますか?
List<Shape>
_に割り当てますが、これはまったく問題ありません。stream()
またはfilter()
は、使用するリストの種類を決定します。Collectors.toList()
は、List
の具象型も指定しません。それで、ここで使用されているList
のconcreteタイプ(サブクラス)は何ですか?保証はありますか?
それでは、Listのどの具体的なタイプ(サブクラス)がここで使用されていますか?保証はありますか?
Collectors#toList()
のドキュメントを見ると、-"リストの型、可変性、直列化可能性、スレッドセーフ性についての保証はありません戻りました!。特定の実装を返したい場合は、代わりに Collectors#toCollection(Supplier)
を使用できます。
Supplier<List<Shape>> supplier = () -> new LinkedList<Shape>();
List<Shape> blue = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.collect(Collectors.toCollection(supplier));
そして、ラムダから、List<Shape>
。
更新:
または、メソッドリファレンスを使用することもできます。
List<Shape> blue = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.collect(Collectors.toCollection(LinkedList::new));
Netbeansをナビゲート(Ctrl +クリック)すると、このコードが表示されます。サプライヤとしてArrayListを使用しているようです。
public static <T> Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}