2016-05-09 4 views
55

Java 8ストリームAPIは非常に素晴らしい機能であり、私は絶対にそれを好きです。私の神経を邪魔することの1つは、コレクションとして入力してコレクションとして出力したい時間の90%です。結果は、私はすべての時間stream()collect()メソッドを呼び出す必要があります:(?C#でのようなlinqを)Java 8 - 退屈な収集方法を省略

collection.stream().filter(p->p.isCorrect()).collect(Collectors.toList()); 

は私がストリームをスキップして、直接コレクションを操作してみましょうであろう任意のJava APIがあります:

Collection#removeIf(Predicate)を使用して
collection.filter(p->p.isCorrect) 
+11

注'(P-> p.isCorrect())という強力なextenedストリーム型

ReactiveSeq.fromIterable(collection) .filter(p->p.isCorrect()) .toList(); 

を利用することができます'(MyClass :: isCorrect)'としてより正確に記述されます。 –

+8

@BoristheSpider、それはなぜより正確ですか? – Andrew

+11

@AndrewTobilkoラムダは、 'static'メソッドの作成、あるいは最悪の場合、匿名' class'の作成を必要とするかもしれません。メソッド参照を使用するということは、これがどれも必要でないことを意味します。 –

答えて

10

コレクションを操作したい場合は、をクリックしてください。

例(10人の最初のVIP顧客のIDを取得):

FluentIterable 
     .from(customers) 
     .filter(customer -> customer.isVIP()) 
     .transform(Client::getId) 
     .limit(10); 
+8

これはStreamsを使用するよりも優れています。そして、 '' Iterable''を返します。これは '' Iterables''(http://docs.guava-libraries.googlecode.com/git/javadoc/com)でより簡潔に行うことができます。 /google/common/collect/Iterables.html#filter(java.lang.Iterable,%20com.google.common.base.Predicate))。 – shmosel

+2

あなたはそうです。しかし、ストリームのコレクション(Collectors.toList())よりも快適な方法を見つけるtoList()メソッドがあります。 – user3364192

+6

@ user3364192 'Collectors。*'に静的インポートを使用する場合、ストリームバージョンはやや簡潔です。 – shmosel

41

はい、:

は、与えられた述語を満たすこのコレクションのすべての要素を削除します。

これは、指定されたコレクションを変更し、新しいコレクションを返さないことに注意してください。しかし、あなたはコレクションのコピーを作成し、それを変更することができます。

public static <E> Collection<E> getFilteredCollection(Collection<E> unfiltered, 
                 Predicate<? super E> filter) { 
    List<E> copyList = new ArrayList<>(unfiltered); 

    // removeIf takes the negation of filter 
    copyList.removeIf(e -> { return !filter.test(e);}); 

    return copyList; 
} 

しかし@Holgerはコメントで示唆するように、あなたのコードでこのユーティリティメソッドを定義することを選択し、どこでもそれを使用する場合は、取得する必要があります。また、述語はフィルタとして機能するように否定する必要があることに注意してくださいフィルタリングされたコレクションを作成し、そのユーティリティの collectメソッドへの呼び出しを委譲します。あなたの発信者コードはより簡潔になります。

public static <E> Collection<E> getFilteredCollection(Collection<E> unfiltered, 
                 Predicate<? super E> filter) { 
    return unfiltered.stream() 
        .filter(filter) 
        .collect(Collectors.toList()); 
} 
+10

述語は否定され( 'filter'と比較して)、' removeIf'は元のコレクションを変更し、新しいものを返さないことに留意してください。 – stholzm

+12

'copyList.removeIf(filter.negate());' – shmosel

+2

Java 9から、あなたは 'collection.stream()。collect(フィルタリング(p - > p.isCorrect )、toList()) 'これは実際に[' filtering']のポイントではありません(http://download.java.net/java/jdk9/docs/api/java/util/stream/Collectors.html#filtering -java.util.function.Predicate-java.util.stream.Collector-)コレクタですが、メソッドを作成するよりもむしろこれを使用したいと思います。 –

7

あなたが元のコレクションを変更することなく、フィルタビューが必要な場合は、グアバのCollections2.filter()を検討してください。

+0

ありがとうございます。私はグアバを完全に忘れてしまった! – user3364192

+5

@ user3364192これは明らかに同じではありません。 'filter()'は 'view'を返すので、' Predicate'は各繰り返し/アクセスで評価され、 'get'は' size'などが 'O(1)'ではなく 'O(n)'演算になります'ArrayList')。ここに提示された3つのソリューションは同等ではありません - それぞれメリットとコストがあります。 –

7

ストリームは、明確に定義されたアーキテクチャを持っています。which you can read a lot about。この道を始める前にそれについて読んでみてください。

しかし、コレクションを実装しないと、そのコードを包括する同様のストリームインターフェイスが実装されます。

次に、あなたのユースケースについていくつかのトリッキーな仮定を行うことができます。あなたはまだコレクションインターフェイスからストリームを開くことができますが、あなたはまっすぐにジャンプすることもできますし、その内側で私が想定しているストリームの開始を処理することができます。

streamableCollection cs = new streamableCollection(); 
    cs.filter(); 
    cs.stream(); 

あなたのIDEは、すべてを実装することができます。すべてをデフォルトの実装に戻してください。

+2

'stream()'メソッドを定義し、 'Stream'ではなく、それを実装する' Streamable'インターフェイスが必要だと思います。これは 'Iterable'と' Iterator'に似ています。 'Stream'と' Iterator'の両方が消費され、再利用できないので、 '* able'インターフェースはもう一度それを実行するたびにファクトリメソッドを定義することでそれを回避します。 –

+1

'StreamableCollection' _do_と' filter'は何でしょうか?基礎となるコレクションを変更すると、それが問題になります。そうでなければ、それは視点であり、それは問題です。私はあなたが賢明にこれを実装できると確信していません。 –

+0

確かに、これはちょっとしたコンセプトの@HankDでした。良い考えと確かにパターンをきれいにする。 – TheNorthWes

17

あなたは、これは不変性を維持しながら、もう少し簡単であるという利点を持っているStreamEx

StreamEx.of(collection).filter(PClass::isCorrect).toList(); 

を使って好きかもしれません。

+2

私はStreamExについて言及することを考えていましたが、このケースではほとんど役に立ちません。 – shmosel

+2

これは、OPが検索しているかもしれないC#APIに近い 'stream' APIを提供します。 – GuiSim

1

あなたはグアバライブラリから、これを試してみてください。 Streamのアプローチよりもちょっと混乱しているようです。

ImmutableList.copyOf(Iterables.filter(collection, MyClass::isCorrect)); 

この技術についての説明は、Google Collections (Guava Libraries): ImmutableSet/List/Map and Filteringを参照してください。

6

私はまた、ストリームAPIは良いと思うが、短い操作では冗長だと思う。私はいくつかのプロジェクトでこれらのユーティリティメソッドを使用しました:

import java.util.List; 
import java.util.function.Function; 
import java.util.function.Predicate; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 

public class Functions { 

    public static <T,V> List<V> map(final List<T> in, final Function<T, V> function) { 
     return in == null ? null : map(in.stream(), function); 
    } 

    public static <T,V> List<V> map(final Stream<T> in, final Function<T, V> function) { 
     return in == null ? null : in 
      .map(function) 
      .collect(Collectors.toList()); 
    } 

    public static <T> List<T> filter(final List<T> in, final Predicate<T> predicate) { 
     return in == null ? null : filter(in.stream(), predicate); 
    } 

    public static <T> List<T> filter(final Stream<T> in, final Predicate<T> predicate) { 
     return in == null ? null : in 
      .filter(predicate) 
      .collect(Collectors.toList()); 
    } 
} 

List<String> wrapped = Functions.map(myList, each -> "[" + each + "]"); 

通常、メソッドも静的にインポートします。

1

はい、Java 8のストリームの冗長性に対応するライブラリがいくつかあります。不完全なリスト:

私の好みはjOOLとなります。私は最後のプロジェクトでそれを使ってきました。私が知っている他の人たちが、私は本当に使っていないので、あなたに印象を与えることはできません。

jOOLとあなたの例では、次のようになります。

Seq.seq(collection).filter(p->p.isCorrect()).toList(); 
3

サードパーティのライブラリを使用することに開いている場合は、コレクションの下に直接利用できる豊富なAPIを持っているEclipse Collectionsを使用することができます。あなたの例はEclipse Collectionsで以下のように書くことができます。

collection.select(p->p.isCorrect) 
collection.select(MyClass::isCorrect) 

注:私はEclipse Collectionsのコミッターです。

0

cyclops-reactにはいくつかのオプションがあります。

我々は怠惰な拡張コレクション

CollectionX<String> collection = ListX.of("hello","world"); 
    CollectionX<String> filtered = collection.filter(p->p.isCorrect()); 

、可変不変かつ持続的な拡張コレクションのサポートがあるのを利用することができます。コレクションの機能操作は遅延(すなわち再生可能なストリームのように振る舞う)であり、最初のアクセス時にのみ実現される。

我々は `[開示、私は反応しサイクロプスのリード開発者です]

関連する問題