web-dev-qa-db-ja.com

Java instanceofおよびクラスキャストのメソッド参照を含むストリーム

メソッド参照を使用して次のコードを変換できますか?

List<Text> childrenToRemove = new ArrayList<>();

group.getChildren().stream()
    .filter(c -> c instanceof Text)
    .forEach(c -> childrenToRemove.add((Text)c));

意味を説明するために例を挙げましょう。

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(elem -> System.out.println(elem));

メソッド参照を使用すると、次のように記述できます(最終行)

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

式をメソッド参照に変換するためのルールは何ですか?

11
GabrielChu

はい、次のメソッド参照を使用できます。

_.filter(Text.class::isInstance)
.map(Text.class::cast)
.forEach(childrenToRemove::add);
_

For-each-addの代わりに、 Collectors.toSet() を使用してストリーム項目を収集できます。

_Set<Text> childrenToRemove = group.getChildren()
    // ...
    .collect(Collectors.toSet());
_

子の順序を維持する必要がある場合は toList() を使用します。

次のルールを適用することで、シグネチャが一致する場合、ラムダ式をメソッド参照に置き換えることができます。

_ContainingClass::staticMethodName // method reference to a static method
containingObject::instanceMethodName // method reference to an instance method
ContainingType::methodName // method reference to an instance method
ClassName::new // method reference to a constructor
_
23
steffen

このスレッドを復活させて申し訳ありませんが、最後の答えは期待される動作に適合しません。 Java docsを読むことにより、サプライヤは空のコレクションを返すことを意味します。収集プロセス中にサプライヤが複数回呼び出される可能性があるため、これは重要です。例:

...collect(Collectors.toCollection(ArrayList::new));

Java doc: JavaDoc への参照

0
Rincewind

はい、可能だと思います。

group.getChildren()
    .filter(Text.class::isInstance)
    .map(Text.class::cast)
    .collect(Collectors.toCollection(() -> childrenToRemove));
0