Is there a concise way to iterate over a stream with indices in Java 8?

后端 未结 22 2742
天命终不由人
天命终不由人 2020-11-22 01:42

Is there a concise way to iterate over a stream whilst having access to the index in the stream?

String[] names = {\"Sam\",\"Pamela\", \"Dave\", \"Pascal\",          


        
22条回答
  •  情书的邮戳
    2020-11-22 02:04

    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 expected = Lists.immutable.with("Erik");
    Predicate> predicate =
        pair -> pair.getOne().length() <= pair.getTwo() + 1;
    
    // JDK Types
    List strings1 = ArrayIterate.zipWithIndex(names)
        .collectIf(predicate, Pair::getOne);
    Assert.assertEquals(expected, strings1);
    
    List list = Arrays.asList(names);
    List strings2 = ListAdapter.adapt(list)
        .zipWithIndex()
        .collectIf(predicate, Pair::getOne);
    Assert.assertEquals(expected, strings2);
    
    // Eclipse Collections types
    MutableList mutableNames = Lists.mutable.with(names);
    MutableList strings3 = mutableNames.zipWithIndex()
        .collectIf(predicate, Pair::getOne);
    Assert.assertEquals(expected, strings3);
    
    ImmutableList immutableNames = Lists.immutable.with(names);
    ImmutableList strings4 = immutableNames.zipWithIndex()
        .collectIf(predicate, Pair::getOne);
    Assert.assertEquals(expected, strings4);
    
    MutableList strings5 = mutableNames.asLazy()
        .zipWithIndex()
        .collectIf(predicate, Pair::getOne, Lists.mutable.empty());
    Assert.assertEquals(expected, strings5);
    

    Here's a solution using forEachWithIndex instead.

    MutableList mutableNames =
        Lists.mutable.with("Sam", "Pamela", "Dave", "Pascal", "Erik");
    ImmutableList expected = Lists.immutable.with("Erik");
    
    List 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

提交回复
热议问题