flatMap() 이후에 filter()가 Java 스트림에서 완전히 게으르지 않은 이유
Java 스트림에서 filter()는 게으른 것으로 간주됩니다. 즉, 즉시 실행되지 않고 소비 시점에 실행됩니다. 그러나 filter()가 flatMap()을 따르는 경우 해당 동작은 진정한 게으름에서 벗어납니다.
데모
다음 코드를 고려하세요.
Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
이 예에서는 filter()가 정수 스트림에 적용됩니다. 출력은 지연 평가에서 예상한 대로 필터링 함수가 첫 번째 요소에 대해서만 호출된다는 것을 보여줍니다.
1 Result: 1
그러나 다음 코드에서는
Stream.of(1, 2, 3) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
필터( ) 함수는 두 개의 flatMap() 작업을 적용하여 생성된 스트림에 적용됩니다. 평면화된 스트림의 첫 번째 요소가 필터 조건을 충족한다는 사실에도 불구하고 필터링 함수는 나머지 요소에 대해 계속 호출됩니다.
-1 0 1 0 1 2 1 2 3 Result: -1
설명
이 동작의 이유는 flatMap()이 원래 스트림의 각 요소에 대해 새 스트림을 생성하기 때문입니다. filter()는 지연 작업으로 남아 있지만 병합 작업은 조기 종료를 지원하지 않습니다. 결과적으로 평탄화 프로세스가 시작되면 나중에 스트림에서 필터 조건이 충족되더라도 중단할 수 없습니다.
의미
이 동작은 예상치 못한 결과를 초래할 수 있습니다. 특히 무한 스트림을 처리할 때 결과가 발생합니다. 예를 들어 flatMap() 작업에 대한 입력 스트림이 무한한 경우 filter() 작업은 일치하는 요소를 찾을 수 없음이 보장되더라도 해당 기능을 무기한 적용하려고 시도합니다.
JDK 수정
여기에 설명된 문제는 Java 10에서 해결되었습니다(Java 8로 백포트되었습니다). 이러한 버전에서는 flatMap()이 조기 종료를 지원하도록 최적화되어 flatMap()을 따르는지 여부에 관계없이 filter() 및 기타 지연 작업의 동작이 일관되게 유지되도록 보장합니다.
위 내용은 Java 스트림에서 `FlatMap()` 뒤의 `filter()`가 항상 지연되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!