If you don't mind using a third-party library, Eclipse Collections has zipWithIndex
and forEachWithIndex
available for use across many types. Here's a set of solutions to this challenge for both JDK types and Eclipse Collections types using 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);
Here's a solution using forEachWithIndex
instead.
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);
If you change the lambdas to anonymous inner classes above, then all of these code examples will work in Java 5 - 7 as well.
Note: I am a committer for Eclipse Collections
intRange()
? Haven't come accross this method in Java 8 till now. – FingerprintIntStream.rangeClosed(x, y)
. – FabrikoidList<String> allCities = map.values().stream().flatMap(list -> list.stream()).collect(Collectors.toList());
– Fabrikoidzip
was removed, along with experimental two-valued streams variously calledBiStream
orMapStream
. The main problem is that to do this effectively Java really needs a structurally-typed pair (or tuple) type. Lacking one, it's easy to create a generic Pair or Tuple class -- it's been done many times -- but they all erase to the same type. – Actressmap(BiFunction<T, Long, R> mapper)
which would provide you with the object and the index. But nope. – Brammer