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に載っています]。