Лямбда-коллектор выбрасывает java.lang.ArrayIndexOutOfBoundsException - PullRequest
0 голосов
/ 01 апреля 2019

Лямбда-выражение периодически вызывает исключение ArrayIndexOutOfBoundsException в моем классе Impl.java.

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 ]

1 голос
/ 01 апреля 2019

Похоже, numberStr[entry.getFirst()] выдает ошибку.В вашем Impl классе numberStr слишком мало элементов.Или используйте отладчик или поместите это перед строкой .stream(), чтобы увидеть, что происходит:

System.out.println("numberStr: " + Arrays.toString(numberStr));
0 голосов
/ 02 апреля 2019

В той же строке, что упоминал Шон java.lang.ArrayIndexOutOfBoundsException: 1 Это исключение ясно говорит о том, что при извлечении данных из массива для 1-го элемента произошла ошибка.

Если вы исправите это, то оно должно работать нормально.Чтобы увидеть более четко, настройте отладчик на numberStr и посмотрите, сколько там элементов, и проверьте, сколько элементов вы получаете из потока.Если вы пытаетесь получить доступ к индексу, который недоступен в вашем массиве.Вы должны увидеть это исключение

...