是否有一种简洁的方法在流上迭代,同时访问流中的索引?
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList;
Stream<Integer> indices = intRange(1, names.length).boxed();
nameList = zip(indices, stream(names), SimpleEntry::new)
.filter(e -> e.getValue().length() <= e.getKey())
.map(Entry::getValue)
.collect(toList());
与这里给出的LINQ示例相比,这似乎相当令人失望
string[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
var nameList = names.Where((c, index) => c.Length <= index + 1).ToList();
有更简洁的方式吗?
此外,似乎拉链已经移动或被拆除…
为了完整起见,这里是涉及我的StreamEx库的解决方案:
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
EntryStream.of(names)
.filterKeyValue((idx, str) -> str.length() <= idx+1)
.values().toList();
这里我们创建了一个EntryStream<Integer, String>,它扩展了Stream<Entry<Integer, String>>,并添加了一些特定的操作,如filterKeyValue或values。也使用了toList()快捷方式。
如果您不介意使用第三方库,Eclipse Collections有zipWithIndex和forEachWithIndex可供跨多种类型使用。下面是针对JDK类型和Eclipse Collections类型使用zipWithIndex的一组解决方案。
String[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
ImmutableList<String> expected = Lists.immutable.with("Erik");
Predicate<Pair<String, Integer>> predicate =
pair -> pair.getOne().length() <= pair.getTwo() + 1;
// JDK Types
List<String> strings1 = ArrayIterate.zipWithIndex(names)
.collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings1);
List<String> list = Arrays.asList(names);
List<String> strings2 = ListAdapter.adapt(list)
.zipWithIndex()
.collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings2);
// Eclipse Collections types
MutableList<String> mutableNames = Lists.mutable.with(names);
MutableList<String> strings3 = mutableNames.zipWithIndex()
.collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings3);
ImmutableList<String> immutableNames = Lists.immutable.with(names);
ImmutableList<String> strings4 = immutableNames.zipWithIndex()
.collectIf(predicate, Pair::getOne);
Assert.assertEquals(expected, strings4);
MutableList<String> strings5 = mutableNames.asLazy()
.zipWithIndex()
.collectIf(predicate, Pair::getOne, Lists.mutable.empty());
Assert.assertEquals(expected, strings5);
下面是一个使用forEachWithIndex的解决方案。
MutableList<String> mutableNames =
Lists.mutable.with("Sam", "Pamela", "Dave", "Pascal", "Erik");
ImmutableList<String> expected = Lists.immutable.with("Erik");
List<String> actual = Lists.mutable.empty();
mutableNames.forEachWithIndex((name, index) -> {
if (name.length() <= index + 1)
actual.add(name);
});
Assert.assertEquals(expected, actual);
如果您将上述lambdas更改为匿名内部类,那么所有这些代码示例都可以在Java 5 - 7中工作。
注意:我是Eclipse Collections的提交者
为了完整起见,这里是涉及我的StreamEx库的解决方案:
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
EntryStream.of(names)
.filterKeyValue((idx, str) -> str.length() <= idx+1)
.values().toList();
这里我们创建了一个EntryStream<Integer, String>,它扩展了Stream<Entry<Integer, String>>,并添加了一些特定的操作,如filterKeyValue或values。也使用了toList()快捷方式。