Java 8には、オブジェクトStreamと、3つのプリミティブなIntStream 、 LongStream、およびDoubleStreamの 4つのストリームインターフェイスがあります。 完全に交換するには、標準スレッドですべてをラップする必要があります。 したがって、
StreamEx
、
IntStreamEx
、
LongStreamEx
および
DoubleStreamEx
を
DoubleStreamEx
。 元のインターフェイスを保存するには、次のような退屈なメソッドを大量に作成する必要がありました。
public class IntStreamEx implements IntStream { private final IntStream stream; @Override public <U> StreamEx<U> mapToObj(IntFunction<? extends U> mapper) { return new StreamEx<>(stream.mapToObj(mapper)); } ... }
また、静的コンストラクターを作成する必要がありました。これは、元のクラスに既にあるものだけでなく、他のものもあります( random.ints()を置き換えるために、
IntStreamEx.of(random)
メソッドがあります)。 しかし、その後、自分の裁量で拡大できるストリームがありました。 以下は、追加機能の簡単な概要です。
人気のコレクターの減少
標準のStream APIでは、多くの場合、
.collect(Collectors.toSet())
または
.collect(Collectors.toList())
を記述する必要があります。
Collectors
静的にインポートしても、冗長に見えます。
StreamEx
メソッド
toSet
、
toList
、
toCollection
、
toMap
、
groupingBy
をいくつかの署名とともに追加しました。 これがIDである場合、キーの関数から
toMap
を省略
toMap
ことができます。 いくつかの例:
List<User> users; public List<String> getUserNames() { return StreamEx.of(users).map(User::getName).toList(); } public Map<Role, List<User>> getUsersByRole() { return StreamEx.of(users).groupingBy(User::getRole); } public Map<String, Integer> calcStringLengths(Collection<String> strings) { return StreamEx.of(strings).toMap(String::length); }
joining
メソッドもコレクターに対応しますが、その前に、ストリームのコンテンツは
String::valueOf
介して渡されます。
public String join(List<Integer> numbers) { return StreamEx.of(numbers).joining("; "); }
検索とフィルタリングを削減
ストリーム内の特定のクラスのオブジェクトのみを選択する必要がある場合があります。
.filter(obj -> obj instanceof MyClass)
書くことができ
.filter(obj -> obj instanceof MyClass)
。 ただし、これではストリームのタイプが明確にならないため、要素のタイプを手動でキャストするか、別のステップ
.map(obj -> (MyClass)obj)
追加する必要があります。
StreamEx
を使用する
StreamEx
これはselectメソッドを使用して簡潔に行われます。
public List<Element> elementsOf(NodeList nodeList) { return IntStreamEx.range(0, nodeList.getLength()).mapToObj(nodeList::item).select(Element.class).toList(); }
ちなみに、
select
メソッドの実装では、マップステップは使用されませんが、フィルタリングの直後にストリームタイプの安全でない変換が適用されるため、パイプラインは再び長くなりません。
多くの場合、ストリームからnullをスローする必要があるため、
nonNull()
メソッドを追加して
filter(Objects::nonNull)
を置き換え
filter(Objects::nonNull)
。 また、ストリームから述語を満たす要素を
remove(Predicate)
メソッドもあります(逆に
filter
)。 メソッド参照をより頻繁に使用できます。
public List<String> readNonEmptyLines(Reader reader) { return StreamEx.ofLines(reader).map(String::trim).remove(String::isEmpty).toList(); }
findAny(Predicate)
および
findFirst(Predicate)
filter(Predicate).findAny()
および
filter(Predicate).findFirst()
ます。
has
メソッドを使用すると、ストリームに特定の要素があるかどうかを確認できます。 同様のメソッドがプリミティブストリームに追加されます。
追加および追加
多くの場合、1つまたは2つの特別な値をストリームに追加するか、2つのストリームを接着する必要があります。 標準の
Stream.concat
を使用することは、ネストされたブラケットを追加し、プログラムを左から右に読むという考えを台無しにするため、あまり良く
Stream.concat
ません。
concat
を置き換えるために
concat
append
および
prepend
を作成しました。これにより、現在のストリームの末尾または先頭に別のストリームまたは特定の値セットを追加できます。
public List<String> getDropDownOptions() { return StreamEx.of(users).map(User::getName).prepend("(none)").toList(); }
次のように配列を展開できます。
public int[] addValue(int[] arr, int value) { return IntStreamEx.of(arr).append(value).toArray(); }
コンパレータ
Java 8では、
Comparator.comparingInt
などのキー抽出メソッドを使用してコンパレーターを作成する方がはるかに簡単です。 最も一般的な並べ替えの状況を減らすために、1つのキーの最大値と最小値を検索し、
sortingBy
、
maxBy
、および
minBy
メソッドのファミリーを
minBy
。
public User getMostActiveUser() { return StreamEx.of(users).maxByLong(User::getNumberOfPosts).orElse(null); }
ところで、コンパレータによる並べ替えがプリミティブストリームに追加されました(便利な場合もあります)。 確かに、ボンネットの下には余分なボクシングがありますが、JITコンパイラーの積極的な最適化に頼ることができます。
反復可能
多くの人は、
Iterable
iterator()
メソッドが含まれているため、
Stream
Iterable
インターフェイス
Stream
実装することを
Iterable
ます。 特に、
Iterable
再利用性を意味し、イテレータはストリームから1回しか取得できないため、これは行われていません。 Stack Overflowは、JDKにはすでにこの規則DirectoryStreamの例外があることを指摘しています。 何らかの方法で、ターミナル
forEach
代わりに通常の
for
ループを使用したい場合があります。 これには多くの利点があります。効果的に最終的なだけでなく、任意の変数を使用できる、例外をスローできる、デバッグが簡単、短いスタックトレースなどです。一般に、ストリームを作成してすぐに使用する場合、大きな罪はないと思います
for
ループで。 もちろん、
Iterable
を受け入れ、それを数回バイパスできるメソッドに渡さないように注意する必要があります。 例:
public void copyNonEmptyLines(Reader reader, Writer writer) throws IOException { for(String line : StreamEx.ofLines(reader).remove(String::isEmpty)) { writer.write(line); writer.write(System.lineSeparator()); } }
あなたがそれを好きなら、それを使用しますが、注意してください。
キーと値をマップする
多くの場合、値が特定の条件を満たす、またはその逆のすべての
Map
キーを処理する必要があります。 これを直接書くのは少し退屈です:
Map.Entry
をいじる必要があり
Map.Entry
。 これを静的メソッド
ofKeys(map, valuePredicate)
および
ofValues(map, keyPredicate)
のフードの下に隠しました。
Map<String, Role> nameToRole; public Set<String> getEnabledRoleNames() { return StreamEx.ofKeys(nameToRole, Role::isEnabled).toSet(); }
エントリーストリーム
より複雑な
Map
処理シナリオのために、別個の
EntryStream
クラスが
EntryStream
さ
EntryStream
オブジェクトのストリーム。
StreamEx
機能を部分的に繰り返しますが、キーと値を個別に処理する追加のメソッドも含まれています。 場合によっては、これにより、新しい
Map
生成と既存の
Map
逆アセンブルの両方が簡単になります。 たとえば、これはMap-Listを反転する方法です(値のリストからの行はキーに分類され、キーは新しい値のリストを形成します)。
public Map<String, List<String>> invert(Map<String, List<String>> map) { return EntryStream.of(map).flatMapValues(List::stream).invert().grouping(); }
flatMapValues
使用し
flatMapValues
。これにより、ストリーム
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
flatMapValues
に
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .
Entry<String, List> Entry<String, String>
, invert
, , grouping
— Map
.
Map
:
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry
EntryStream
.
. , - . — GitHub , Maven Central . JavaDoc , . , , - .