다음 문은 사실인가요?
sorted()
동작 후속 작업이 더 이상지지 컬렉션 작동 없다는 것을 의미는 "중간 동작 상태"이지만, 내부 상태에.
( 소스 와 소스 - 그들은 서로 복사하거나 동일한 소스에서 온 것 같다.)
내가 테스트 한 Stream::sorted
위의 소스 코드 조각으로 :
final List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
list.stream()
.filter(i -> i > 5)
.sorted()
.forEach(list::remove);
System.out.println(list); // Prints [0, 1, 2, 3, 4, 5]
효과가있다. 나는 대체 Stream::sorted
와 함께 Stream::distinct
, Stream::limit
그리고 Stream::skip
:
final List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
list.stream()
.filter(i -> i > 5)
.distinct()
.forEach(list::remove); // Throws NullPointerException
내 놀랍게도이 NullPointerException
발생합니다.
모든 시험 방법은 다음과 상태 중간 동작 특성을. 그러나,이 독특한 동작은 Stream::sorted
문서화되지 않으며 스트림 운영 및 파이프 라인 부분은 있는지 설명 상태 중간 작업은 정말 새로운 소스 수집을 보장합니다.
어디에 혼란에서 오는 이상 행동의 설명은 무엇인가?
API 설명서는, 따라서, 특정 구현의 이러한 행동에 의존해서는 안됩니다 "후속 작업이 더 이상 기가되는 콜렉션에서 작동 없다"그러한 보증을하지 않습니다.
귀하의 예를 실수로 원하는 일을하는 일; 것을 보증도이 아니다 List
만든 collect(Collectors.toList())
지원하는 remove
작업은.
카운터 - 예를 표시하려면
Set<Integer> set = IntStream.range(0, 10).boxed()
.collect(Collectors.toCollection(TreeSet::new));
set.stream()
.filter(i -> i > 5)
.sorted()
.forEach(set::remove);
발생합니다 ConcurrentModificationException
. 그 이유는 소스가 이미 정렬로 구현이 시나리오를 최적화한다는 것입니다. 원칙적으로, 그것으로, 원래 예를 들어 동일한 최적화를 할 수있는 forEach
명시 적으로 지정하지 순서로 작업을 수행하고, 따라서 정렬이 필요하지 않습니다.
예를 들어, 상상할 수있는 다른 최적화있다 sorted().findFirst()
정렬 새 스토리지로 요소를 복사 할 필요없이 "최소를 찾아"작업로 변환 얻을 수는.
결론은 그래서 할 수없는 동작에 의존 할 때, 어떤 새로운 최적화가 추가 내일을 깰 수있다, 오늘 일이 일어날 수 있습니다.