Lambda Collector抛出java.lang.ArrayIndexOutOfBoundsException

时间:2019-04-01 12:48:04

标签: java-8 java-stream

Lambda表达式在我的Impl.java类中间歇性地引发ArrayIndexOutOfBoundsException。

Stacktrace:

java.lang.ArrayIndexOutOfBoundsException: 1 java.lang.ArrayIndexOutOfBoundsException: 1
    at Impl.lambda$retrieve$0(Impl.java:124) ~[classes/:?]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[?:1.8.0_181]
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[?:1.8.0_181]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_181]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[?:1.8.0_181]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_181]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_181]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[?:1.8.0_181]
    at Impl.retrieve(Impl.java:125) ~[classes/:?]

我编写了一个模拟场景的示例程序。但是,在示例程序中,它是不可复制的。但是,有人可以找出以下代码有什么问题吗?

我尝试使用空/非空输入。当我使numberStr引发ArrayIndexOutOfBoundsException时,堆栈跟踪显示为不同:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at LambdaTest.lambda$0(LambdaTest.java:13)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at LambdaTest.main(LambdaTest.java:14)

示例程序:

import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.math3.util.Pair;

import com.google.common.collect.Lists;

public class LambdaTest {

    public static void main(String[] args) {
        String[] numberStr = { "one", "two", "three" };
        List<Pair<String, SampleEnum>> result = getInputPairs().stream()
                .map(entry -> new Pair<String, SampleEnum>(numberStr[entry.getFirst()], entry.getSecond()))
                .collect(Collectors.toList()); // <=== similar to Impl.java:125
        System.out.println("Lambda tested." + result.toString());
    }

    private static List<Pair<Integer, SampleEnum>> getInputPairs() {
        List<Pair<Integer, SampleEnum>> pairs = Lists.newArrayList();
        //pairs.add(new Pair<Integer, SampleEnum>(0, SampleEnum.ONE_AND_ONLY));
        return pairs;
    }

}

enum SampleEnum {
    ONE_AND_ONLY
}

在什么情况下,表达式可以失败?以及如何解决?

2 个答案:

答案 0 :(得分:1)

好像numberStr[entry.getFirst()]抛出了错误。在您的Impl类中,numberStr的元素很少。使用调试器,或将其放在.stream()行之前,以查看发生了什么:

System.out.println("numberStr: " + Arrays.toString(numberStr));

答案 1 :(得分:0)

与肖恩(Sean)在同一行  java.lang.ArrayIndexOutOfBoundsException: 1 该异常清楚地表明,在从Array中为第一个元素获取数据时,它失败了。

如果您解决了这个问题,那么它应该可以正常工作。为了更清楚地看到,请在numberStr处设置调试器,查看其中有多少个元素,并检查您从流中获取了多少个元素。如果您尝试访问数组中不可用的索引。您应该看到此异常