2016-11-29 2 views
3

이 질문에 다르게 작업 정렬 방법에 대한 실행 기준은 somhow Java 8 Stream - Filter and foreach method not printing as expected 내가 정렬, 필터 및 Java 8 스트림의지도 방법 함께 일하고자바 8 스트림 - 필터 및지도 방법

관련이있다.

Stream.of("d2", "a2", "b1", "b3", "c") 
.sorted((s1, s2) -> { 
    System.out.printf("sort: %s; %s\n", s1, s2); 
    return s1.compareTo(s2); 
}) 
.filter(s -> { 
    System.out.println("filter: " + s); 
    return s.startsWith("a"); 
}) 
.map(s -> { 
    System.out.println("map: " + s); 
    return s.toUpperCase(); 
}) 
.forEach(s -> System.out.println("forEach: " + s)); 

을 그리고 내가 가진 출력은 다음과 같습니다 :

종류 다음과 같이 위에서 언급 한 질문의 답변에 지정된 필터와 맵의 작동 방식을 염두에 키핑, 나는 정렬 방법을 시도 A2를 ; d2 정렬 : b1; a2 정렬 : b1; d2 정렬 : b1; a2 정렬 : b3; b1 정렬 : b3; d2 정렬 : c; b3 정렬 : c; D2 필터 : 지도 A2 : A2 필터 : B1 필터 : B3 필터 : 대해 forEach A2 필터 C :이다

D2 이제 정렬 방법은 완전한 루프를 실행하고있다 필터 및 맵 기능은 개별 항목에서 실행됩니다. 3 개 모두 중간 기능이므로 모두 동일한 방식으로 작동해야합니다. 실행 순서가 괜찮습니까? 나는 내가 잘못하고있는 것을 얻지 못하고있다.

+4

어떻게 당신이 그들을 보는 모든없는 요소를 정렬 할 수 있습니다? 'distinct()'와 동일합니다. 여전히 게으르다.'forEach'가 없으면'sorted' 연산이 호출되지 않을 것이다. – Tunaki

+8

@KaranVerma 정말 많은 질문을하고 몇 가지를 읽는 것을 중단해야합니다. – Eugene

+0

스트림 파이프 라인은 forEach가 순서가 지정되지 않은 터미널 op이기 때문에 여기에서 정렬을 완전히 제거 할 수 있습니다. 이전 버전에서는 그랬지만, 때로는 공격적으로 적용되기 때문에 최적화가 제거되었습니다. – the8472

답변

3

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

부작용

부작용 행동 매개 변수에 스트리밍하는 작업, 그들은 종종 무국적 요구 사항의 고의 침해로 이어질 수있는만큼, 실망, 일반적으로 다른 스레드 안전 위험이 있습니다.

[...] 또한 이러한 효과의 순서는 놀랄 수 있습니다. 파이프 라인이 스트림 소스의 만남 순서와 일치하는 결과를 생성하도록 제약을받는 경우에도 (예 : IntStream.range(0,5).parallel().map(x -> x*2).toArray() must produce [0, 2, 4, 6, 8])), 매퍼 함수가 개별 요소에 적용되는 순서 또는 어떤 스레드에 대해 보장되지 않습니다 모든 행위 매개 변수는 주어진 요소에 대해 실행됩니다.

enter image description here

+1

그 이미지 ... 그것은 우스운 이야기와 이상한 것입니다. – Eugene

3

"의존" 스트림 작업은 순서가 분명 해지 자마자 각 단계에서 항목을 내보낼 수 있기 때문에 인터리브 할 수 있습니다. 필터링 및 매핑의 경우 각 항목은 처리되고 삼켜 지거나 전달 될 수 있습니다.

정렬의 경우, 모두 정렬 알고리즘에 따라 다릅니다. 정렬이 "n-1 비교가있는 모든 요소의 최소값을 찾고, 최소값을 내고, 나머지 값과 반복"을 구현하는 것으로 정렬을 구현하는 경우, 정렬은 실제로 필터링 및 매핑과 인터리브됩니다. 그러나 출력 결과를 보면 삽입 정렬 (삽입 지점에 대한 이진 검색 또는 일부 검색 트리 포함)과 유사합니다. a2/d2가 결과 (a2, d2)와 비교됩니다. b1과 a2, b1, b3, d2) 사이에 b1을 비교 한 다음 b2를 b1과 비교 한 다음 d2를 b2와 b2 사이에 삽입합니다. 정렬 된 O (nlogn) 시간 (반복 된 최소 찾기의 경우 O (n^2)과 비교됨)이 나오기 때문에 의미가 있지만 마지막 요소가 삽입 될 때까지 아무 것도 내보낼 수 없습니다. 즉, 필터링이 시작되기 전에 정렬이 완료되어야합니다.

+1

오, 내 대답을 명확히하기 위해 : 당신은 아무 잘못도 없습니다. 내 대답은 왜 당신의 산출물이 왜 합리적으로 합당한지를 받아들이고 이해하도록 도와 줄 것입니다. –