ArrayList
является не потокобезопасной коллекцией, и вы пытаетесь обновить ее из многочисленных потоков с помощью parallelStream
, что, как вы видите, является результатом resizing
внутреннего массива этого ArrayList
- эта операция также не является поточно-ориентированной, сначала вы увеличиваете массив и , затем перемещаете в него элементы: возможно, элементы не были перемещены, и вы пытаетесь получить к нему доступ.
Всделать это более явным, когда происходит изменение размера, создается массив новый с увеличенным размером - этот новый массив, если он заполнен null
s только после копирования.
Это действительно непредсказуемо, что произойдет, просто не надейтесь ни на что из этого.
РЕДАКТИРОВАТЬ
Я не могу опубликовать это как комментарий,но вот код, подтверждающий, что null
можно увидеть:
List<Integer> result = IntStream.iterate(0, i -> i + 1)
.takeWhile(i -> {
String arr[] = { "A", "B", "C", "D", "E", "F", "G", "H", "R", "T" };
List<String> list = new ArrayList<>();
Arrays.stream(arr)
.parallel()
.peek(list::add)
.forEach(x -> {
});
if (list.contains(null)) {
System.out.println("It took " + i + " steps to see a null");
return false;
}
return true;
})
.boxed()
.collect(Collectors.toList());