如何使用索引迭代流

1.概述

Java 8 Streams不是集合,並且無法使用它們的索引來訪問元素,但是仍然有一些技巧可以實現這一點。

在這短短的文章中,我們將看看如何遍歷一個Stream使用IntStream, StreamUtils, EntryStream,VavrStream

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()方法可以完成索引的另一種迭代方法(可在此處找到最新版本)。

首先,您需要將其添加到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()進行索引迭代(可在此處找到最新版本)。首先,我們需要將其添加到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.使用**VavreStream**迭代

另一個可行的迭代方式是使用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的更多信息,請查看本文。

六,結論

在本快速教程中,我們看到了四種如何使用索引迭代流的方法。流已經引起了很多關注,並且還可以使用索引對其進行迭代可能會有所幫助。

Java 8 Streams包含許多功能,Baeldung已經涵蓋了其中的一些功能。

此處說明的所有示例的代碼,以及更多內容都可以在GitHub上找到