478

コレクションを簡単にフィルタリングするために、Java 8ラムダをいじっていました。しかし、結果を同じステートメント内の新しいリストとして取得する簡潔な方法が見つかりませんでした。これまでの私の最も簡潔なアプローチは次のとおりです。

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);

ネット上の例は、新しい結果リストを生成せずに停止するため、私の質問に答えませんでした。もっと簡潔な方法があるはずです。クラスには、 、 … のStreamようなメソッドがあると予想していました</p> toList()toSet()

変数targetLongListを 3 行目で直接代入する方法はありますか?

4

15 に答える 15

653

ストリームがシーケンシャルのままであれば、あなたがしていることは最も簡単な方法かもしれませんforEach

[後で編集: sequential() の呼び出しが必要な理由はforEach(targetLongList::add)、ストリームが並列である場合、そのままのコード ( ) が際どいものになるためです。forEachそれでも、明示的に非決定論的であるため、意図した効果は得られません。シーケンシャル ストリームであっても、要素処理の順序は保証されません。forEachOrdered正しい順序を確保するために使用する必要があります。ストリーム API 設計者の意図は、以下のように、この状況でコレクターを使用することです。]

代替案は

targetLongList = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(Collectors.toList());
于 2013-02-12T12:22:50.387 に答える
192

更新しました:

別のアプローチは、次を使用することCollectors.toListです。

targetLongList = 
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toList());

以前の解決策:

別のアプローチは、次を使用することCollectors.toCollectionです。

targetLongList = 
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toCollection(ArrayList::new));
于 2013-03-17T06:28:20.593 に答える
13

ArrayList私は、必要なときにコレクターを返す util メソッドを使用するのが好きです。

Collectors.toCollection(ArrayList::new)使用するソリューションは、このような一般的な操作には少しうるさいと思います。

例:

ArrayList<Long> result = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(toArrayList());

public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
    return Collectors.toCollection(ArrayList::new);
}

この回答で、一般的に非常に便利なカスタム コレクターの作成と使用がいかに簡単かを示したいと思います。

于 2015-11-20T09:15:39.923 に答える
6
collect(Collectors.toList());

これは、ストリームをリストに変換するために使用できる呼び出しです。

より具体的に:

    List<String> myList = stream.collect(Collectors.toList()); 

から:

https://www.geeksforgeeks.org/collectors-tolist-method-in-Java-with-examples/

于 2017-09-18T10:03:46.913 に答える
5

プリミティブの配列がある場合は、Eclipse Collectionsで使用可能なプリミティブ コレクションを使用できます。

LongList sourceLongList = LongLists.mutable.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
LongList targetLongList = sourceLongList.select(l -> l > 100);

sourceLongList を次から変更できない場合List:

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = 
    ListAdapter.adapt(sourceLongList).select(l -> l > 100, new ArrayList<>());

使用したい場合LongStream

long[] sourceLongs = new long[]{1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L};
LongList targetList = 
    LongStream.of(sourceLongs)
    .filter(l -> l > 100)
    .collect(LongArrayList::new, LongArrayList::add, LongArrayList::addAll);

注: 私は Eclipse Collections の寄稿者です。

于 2016-03-27T00:08:41.900 に答える
1

サードパーティのライブラリを使用してもかまわない場合は、AOL のcyclops-react lib (私が寄稿者であることの開示) には、Listを含むすべてのJDK Collectionタイプの拡張機能があります。ListX インターフェースは java.util.List を拡張し、フィルターを含む多数の便利な演算子を追加します。

あなたは単に書くことができます-

ListX<Long> sourceLongList = ListX.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
ListX<Long> targetLongList = sourceLongList.filter(l -> l > 100);

ListX は既存のリストから作成することもできます (ListX.fromIterable 経由)。

于 2016-02-25T10:18:01.997 に答える
0

誰か(私のような)がプリミティブ型の代わりにオブジェクトを処理する方法を探している場合は、mapToObj()

String ss = "An alternative way is to insert the following VM option before "
        + "the -vmargs option in the Eclipse shortcut properties(edit the "
        + "field Target inside the Shortcut tab):";

List<Character> ll = ss
                        .chars()
                        .mapToObj(c -> new Character((char) c))
                        .collect(Collectors.toList());

System.out.println("List type: " + ll.getClass());
System.out.println("Elem type: " + ll.get(0).getClass());
ll.stream().limit(50).forEach(System.out::print);

プリント:

List type: class java.util.ArrayList
Elem type: class java.lang.Character
An alternative way is to insert the following VM o
于 2015-10-02T15:42:21.093 に答える
0

ここにAbacusUtilによるコードがあります

LongStream.of(1, 10, 50, 80, 100, 120, 133, 333).filter(e -> e > 100).toList();

開示: 私は AbacusUtil の開発者です。

于 2016-12-02T07:46:37.757 に答える
0

変更可能なリストで収集するには:

targetList = sourceList.stream()
                       .filter(i -> i > 100) //apply filter
                       .collect(Collectors.toList());

不変リストで収集するには:

targetList = sourceList.stream()
                       .filter(i -> i > 100) //apply filter
                       .collect(Collectors.toUnmodifiableList());

JavaDoccollectからの説明:

Collector を使用して、このストリームの要素に対して変更可能なリダクション操作を実行します。Collector は、collect(Supplier、BiConsumer、BiConsumer) の引数として使用される関数をカプセル化し、コレクション戦略の再利用と、複数レベルのグループ化やパーティション化などの収集操作の構成を可能にします。ストリームが並列で、コレクターが並行であり、ストリームが順序付けされていないかコレクターが順序付けられていない場合、並行削減が実行されます (並行削減​​の詳細については、コレクターを参照してください)。

これは端末操作です。

並行して実行すると、可変データ構造の分離を維持するために、複数の中間結果がインスタンス化、移入、およびマージされる場合があります。したがって、スレッドセーフでないデータ構造 (ArrayList など) と並列に実行された場合でも、並列リダクションのために追加の同期は必要ありません。

于 2020-06-06T18:25:20.177 に答える
0
String joined = 
                Stream.of(isRead?"read":"", isFlagged?"flagged":"", isActionRequired?"action":"", isHide?"hide":"")
                      .filter(s -> s != null && !s.isEmpty())
                      .collect(Collectors.joining(","));
于 2017-02-23T22:54:23.510 に答える
-3

これを使わなければうまくparallel()いく

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);

List<Long> targetLongList =  new ArrayList<Long>();

sourceLongList.stream().peek(i->targetLongList.add(i)).collect(Collectors.toList());
于 2016-08-12T07:04:25.367 に答える