2016-10-11 1 views
2

을 변경하지 않습니다.java8 스트림은이 코드를 클래스 멤버

stream::map 뒤에 어떻게이 항목이 namesSet에 추가되지 않습니까?

Set<String> namesSet; 

@Override 
public boolean isValid(List<String> input) { 
    namesSet = new HashSet<>(); 
    input.stream().forEach(item -> namesSet.add(item)); 
    return namesSet.size() == input.size(); 
} 
+3

스트림이 뭔가를 변경하고자하는 것은 아니다. 그것들은 결과를 평가하도록 설계되었습니다. 그리고'map'은 이름에서 알 수 있듯이 값에서 다른 것으로 맵핑해야합니다. 따라서 결과를 평가하는 실제 * 터미널 작동 *이 없으면 아무 것도 일어나지 않습니다. Streams가'namesSet.addAll (input); '을보다 장황하게 말하는 방법을 제공하도록 설계 되었다면 ... 바보가 될 것입니다 ... – Holger

+3

"fixed"코드는 여전히 쓸모없는 스트림입니다. 'namesSet = new HashSet <> (input)을 사용하면된다. namesets.size() == input.size();'를 반환합니다. Streams를 어떤 비용으로 가져오고 자한다면, 깨끗한 방법은'namesSet = input.stream(). collect (Collectors.toSet()); namesets.size() == input.size();'를 반환합니다. – Holger

+1

또는'input.stream(). distinct(). count() == input.size()'. 중복 된 필드를 제거하십시오. –

답변

6

스트림 작업이 게으른 당신은 forEach 또는 collect 같은 터미널 작업을 종료하지 않는 한 실행되지 않습니다

갱신 여기 내 수정합니다.

이 경우 map 대신 forEach을 사용하십시오. map은 중간 작업입니다.

그런데, isValid 메서드가 필드를 수정하는 매우 불쾌한 부작용처럼 들립니다. 한 번 호출하여 true을 얻은 경우 두 번째 호출에서 false이 표시됩니다. 어쨌든, 나는이 방법을 이해할 수 없다. (한번 고치면) 첫 번째 호출에서는 항상 true을 반환하고 모든 후속 호출에서는 false을 반환하기 때문이다. 유일한 예외는 빈 목록입니다.이 경우 항상 true을 반환합니다.

편집 : 당신은 그냥 목록에 중복 포함되어 있는지 여부를 찾으려면

당신은 다만 수, 당신의 방법에 대해 자세히 살펴 갖는 here에서

input.stream().distinct().count() == input.size() 
+1

OP는 이 작업을 위해'forEach'를 사용하십시오. 'namesSet.addAll (input); '이 원하는 연산 인 경우, Stream API를 불필요하게 사용하지 않고 그대로 써야합니다. – Holger

+0

@Holger 솔직히 말해서, 마지막 단락에서 썼 듯이 전체 메서드는 코드 냄새입니다. –

+0

이 메소드를 수정했습니다. 코드 냄새 –

0

합니다.

"중간 작업은 항상 게으르며, filter()와 같은 중간 작업을 실행하면 실제로는 필터링이 수행되지 않고 통과 할 때 초기 요소를 포함하는 새로운 스트림이 생성됩니다 파이프 라인 소스의 순회는 파이프 라인의 터미널 작업이 실행될 때까지 시작되지 않습니다. "

그래서 터미널 작업을 호출해야합니다.

2

문제를 해결하기 위해 Stream API를 사용하면 이 필요하지 않습니다.

그냥 당신이 List와 비교 크기 (HashSetcopy constructor 사용)의 내용으로 Set을 만듭니다

@Override 
public boolean isValid(List<String> input) { 
    Set<String> namesSet = new HashSet<>(input); // copies the content of 'input' 
    return namesSet.size() == input.size(); 
}