インデックス付きのストリームを反復する方法
1概要
Java 8
Streams
はコレクションではないので、要素にインデックスを使ってアクセスすることはできませんが、これを可能にするためのトリックがまだいくつかあります。
この短い記事では、
IntStream、
StreamUtils、EntryStream、
、および
Vavr
sの
Stream
を使用して
Stream
を反復処理する方法について説明します。
2プレーンJava
の使い方
Integer
の範囲を使用して
Stream
をナビゲートすることができます。また、元の要素が配列またはインデックスからアクセス可能なコレクション内にあるという事実から利益を得ることもできます。
インデックスを使って繰り返し、このアプローチを実証するメソッドを実装しましょう。
簡単に言うと、
Strings
の配列を取得し、インデックス付きの要素だけを選択したいのです。
public List<String> getEvenIndexedStrings(String[]names) {
List<String> evenIndexedNames = IntStream
.range(0, names.length)
.filter(i -> i % 2 == 0)
.mapToObj(i -> names[i])
.collect(Collectors.toList());
return evenIndexedNames;
}
実装をテストしましょう。
@Test
public void whenCalled__thenReturnListOfEvenIndexedStrings() {
String[]names
= {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
List<String> expectedResult
= Arrays.asList("Afrim", "Besim", "Durim");
List<String> actualResult
= StreamIndices.getEvenIndexedStrings(names);
assertEquals(expectedResult, actualResult);
}
3
StreamUtils
を使用する
proton-pack
ライブラリにある
StreamUtils
の__zipWithIndex()メソッドを使用して、インデックスを使用して反復することができます(最新バージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg %3A%22com.codepoetics%22%20AND 20a%3A%22プロモーションパック%22[ここ]。
まず、あなたの
pom.xml
にそれを追加する必要があります。
<dependency>
<groupId>com.codepoetics</groupId>
<artifactId>protonpack</artifactId>
<version>1.13</version>
</dependency>
それでは、コードを見てみましょう。
public List<Indexed<String>> getEvenIndexedStrings(List<String> names) {
List<Indexed<String>> list = StreamUtils
.zipWithIndex(names.stream())
.filter(i -> i.getIndex() % 2 == 0)
.collect(Collectors.toList());
return list;
}
次のメソッドはこのメソッドをテストして成功します。
@Test
public void whenCalled__thenReturnListOfEvenIndexedStrings() {
List<String> names = Arrays.asList(
"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim");
List<Indexed<String>> expectedResult = Arrays.asList(
Indexed.index(0, "Afrim"),
Indexed.index(2, "Besim"),
Indexed.index(4, "Durim"));
List<Indexed<String>> actualResult
= StreamIndices.getEvenIndexedStrings(names);
assertEquals(expectedResult, actualResult);
}
4
StreamEx
を使用する
StreamEx
ライブラリの
EntryStream
クラスの
filterKeyValue()
を使用してインデックスを反復することもできます(最新バージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22one.utilにあります) %22%20AND%20a%3A%22streamex%22[ここ]。
まず、それを__pom.xmlに追加する必要があります。
<dependency>
<groupId>one.util</groupId>
<artifactId>streamex</artifactId>
<version>0.6.5</version>
</dependency>
前の例を使って、このメソッドを簡単に適用してみましょう。
public List<String> getEvenIndexedStringsVersionTwo(List<String> names) {
return EntryStream.of(names)
.filterKeyValue((index, name) -> index % 2 == 0)
.values()
.toList();
}
これをテストするために同様のテストを使用します。
@Test
public void whenCalled__thenReturnListOfEvenIndexedStringsVersionTwo() {
String[]names
= {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
List<String> expectedResult
= Arrays.asList("Afrim", "Besim", "Durim");
List<String> actualResult
= StreamIndices.getEvenIndexedStrings(names);
assertEquals(expectedResult, actualResult);
}
5
Vavre
´s
Stream
を使った繰り返し
もう1つ考えられる反復方法は、
Vavr
(以前は
Javaslang
)の
Stream
実装の
zipWithIndex()
メソッドを使用することです。
public List<String> getOddIndexedStringsVersionTwo(String[]names) {
return Stream
.of(names)
.zipWithIndex()
.filter(tuple -> tuple.__2 % 2 == 1)
.map(tuple -> tuple.__1)
.toJavaList();
}
次の方法でこの例をテストできます。
@Test
public void whenCalled__thenReturnListOfOddStringsVersionTwo() {
String[]names
= {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
List<String> expectedResult
= Arrays.asList("Bashkim", "Lulzim", "Shpetim");
List<String> actualResult
= StreamIndices.getOddIndexedStringsVersionTwo(names);
assertEquals(expectedResult, actualResult);
}
Vavrについてもっと知りたい場合は、/vavrにリンクしてください。
6. 結論
このクイックチュートリアルでは、インデックスを使用してストリームを反復処理する方法について4つのアプローチを説明しました。ストリームは多くの注目を集めており、インデックスを使ってストリームを繰り返すこともできると便利です。
Java 8 Streamsにはたくさんの機能が含まれていますが、その一部はすでに
Baeldung
でカバーされています。
ここで説明したすべての例のためのコード、そしてもっと多くのものがhttps://github.com/eugenp/tutorials/tree/master/java-streams[GitHubに載っています]。