Java 8 Stream 不是集合,不能通过索引方式访问。本文介绍几种方法实现,包括
IntStream
,StreamUtils
,EntryStream
, 以及Vavr
的 Stream。
1. 使用普通Java类实现
我们可以使用 Integer 范围遍历流,这样可以通过索引方式访问数组或集合中的元素。下面示例展示如何访问字符串数组,仅或取索引为偶数的元素。
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;
}
2. 使用 StreamUtils
这里使用 protonpack
库中 StreamUtils
提供的方法 zipWithIndex() 实现通过索引迭代。首先引入依赖:
<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;
}
3. 使用 StreamEx
库
StreamEx 库提供 EntryStream 类的方法 filterKeyValue 。首先导入依赖:
<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();
}
4. 使用 Vavr 库的Stream
最后是 Vavr 库提供的Stream 实现,引入依赖:
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.9.0</version>
</dependency>
主要使用Stream类的 zipWithIndex() 方法,实现代码:
public List<String> getOddIndexedStringsVersionTwo(String[] names) {
return Stream
.of(names)
.zipWithIndex()
.filter(tuple -> tuple._2 % 2 == 1)
.map(tuple -> tuple._1)
.toJavaList();
}
5. 总结
本文介绍了四种方法实现索引方式遍历流。流已经有广泛的使用,能够使用索引迭代有时会更方便。