2014-07-19 5 views
4

다음 코드가 올바른 이유를 이해합니다. 터미널 작업을 호출하기 전에 컬렉션이 수정되기 때문입니다.자바 8 스트림 간섭 대 비 간섭

List<String> wordList = ...; 
Stream<String> words = wordList.stream(); 
wordList.add("END"); // Ok 
long n = words.distinct().count(); 

하지만이 코드는 왜 잘못 되었습니까?

Stream<String> words = wordList.stream(); 
words.forEach(s -> if (s.length() < 12) wordList.remove(s)); // Error—interference 

답변

5

Stream.forEach() 터미널 작업이며, 기본 단어 목록 수집 단말기가 시작된 후/호출 변경된다.

+0

Thx. 나는 터미널 작전 이었다는 것을 몰랐다. –

4

Joachim's answer이 맞습니다.

특별히 묻지는 않았지만 다른 독자의 이익을 위해 스트림 간섭 문제를 피하면서 프로그램을 다른 방식으로 다시 작성하기위한 몇 가지 기술이 있습니다. 당신이 현재 위치에서 목록을 돌연변이하려면

대신 사용하여 스트림의 List에 새 기본 방법으로 수행 할 수 있습니다 :

wordList.removeIf(s -> s.length() < 12); 

당신이 그대로 원래의 목록을두고 있지만을 만들려면 내가 filter 때문에, 조건의 의미를 반전했다

List<String> newList = wordList.stream() 
    .filter(s -> s.length() >= 12) 
    .collect(Collectors.toList()); 

참고 버지니아를 유지하는 술어를 취 수정 복사, 당신은 그렇게 할 수있는 스트림과 컬렉터를 사용할 수 있습니다 조건이 참일 경우 스트림에서 채 웁니다.