Collection.stream().forEach()와 Collection.forEach()의 차이점은 무엇입니까?
는 그것을 한다..stream()
이렇게 연쇄 을 할 수 .filter()
병렬 스트림을 사용합니다.그러나 작은 작업(리스트 요소 인쇄 등)을 수행해야 하는 경우에는 어떤 차이가 있습니까?
collection.stream().forEach(System.out::println);
collection.forEach(System.out::println);
그림과 같이 간단한 경우는 거의 동일합니다.그러나 중요한 몇 가지 미묘한 차이가 있습니다.
한 가지 문제는 주문에 관한 것입니다.★★★★★★★★★★★★★★★★ Stream.forEach
순서는 정의되어 있지 않습니다.시퀀셜 스트림에서는 발생하지 않을 가능성이 높지만 다음 사양에 준거하고 있습니다.Stream.forEach
을 사용법이 문제는 병렬 스트림에서 자주 발생합니다. by by by by byIterable.forEach
됩니다.Iterable
(일부러)
을 하다에서 Stream.forEach
간섭하지 않아야 합니다.(java.util.stream 패키지 문서를 참조하십시오). Iterable.forEach
제한사항이 적을 수 있습니다.「 」의 는,java.util
,Iterable.forEach
으로는 그 that that that that that that that that that that that that that 를 사용합니다.Iterator
이 중 대부분은 Fail Fast를 지원하도록 설계되어 있습니다.ConcurrentModificationException
반복 중에 컬렉션이 구조적으로 변경된 경우.그러나 반복 중에는 구조적이지 않은 수정이 허용됩니다.예를 들어 ArrayList 클래스 문서에는 "요소의 값만 설정하는 것은 구조 수정이 아닙니다."라고 나와 있습니다.그 때문에, 의 액션은ArrayList.forEach
값 됩니다.ArrayList
문제없이.
동시 컬렉션이 다시 다릅니다.Fail-Fast 대신 일관성이 약하도록 설계되어 있습니다.완전한 정의는 그 링크에 있습니다.단, 간단히 생각해 봅시다.ConcurrentLinkedDeque
은 .션 to to its its its its its its its its forEach
메서드는 구조적으로도 기본 디큐를 변경할 수 있습니다.ConcurrentModificationException
절대 던지지 않습니다.의 일관성을.)(어느 쪽인가 하면)
다른 , 라고 하면 또 다른 차이점이 보인다.Iterable.forEach
동기화된 수집을 반복하고 있습니다.에서는, 「 」의Iterable.forEach
는 컬렉션의 잠금을 1회 취득하여 액션메서드에 대한 모든 콜에서 잠금을 유지합니다.그Stream.forEach
콜은 콜의 스플리터를 사용합니다.이 스플리터는 잠기지 않고 일반적인 비간섭 규칙에 의존합니다.반복 할 수 스트림을 지원하는 컬렉션을 할 수 .★★★★★★★★★★★★★★★★,ConcurrentModificationException
또는 일관성이 없는 동작이 발생할 수 있습니다.
이 답변은 루프의 다양한 실장의 퍼포먼스와 관련이 있습니다.이것은 매우 자주(수백만 개의 콜과 같이)라고 불리는 루프에 약간만 관련이 있습니다.대부분의 경우 루프의 내용은 단연코 가장 비용이 많이 드는 요소가 됩니다.루프 빈도가 매우 높은 상황에서도, 이것은 여전히 도움이 될 수 있습니다.
이 테스트는 구현에 따라 다르므로 대상 시스템에서 반복해야 합니다(전체 소스 코드).
고속 Linux 시스템에서 openjdk 버전 1.8.0_111을 실행하고 있습니다.
^6은 다양한 크기의 코드를 사용하여 목록 했습니다.integers
(10^0 -> 10^5 엔 ( 。
결과는 다음과 같습니다.가장 빠른 방법은 목록의 항목 수에 따라 달라집니다.
그러나 여전히 최악의 상황에서는 10^5 엔트리를 10^6회 이상 반복하는 데 100초가 걸리기 때문에 거의 모든 상황에서 다른 고려사항이 더 중요합니다.
public int outside = 0;
private void iteratorForEach(List<Integer> integers) {
integers.forEach((ii) -> {
outside = ii*ii;
});
}
private void forEach(List<Integer> integers) {
for(Integer next : integers) {
outside = next * next;
}
}
private void forCounter(List<Integer> integers) {
for(int ii = 0; ii < integers.size(); ii++) {
Integer next = integers.get(ii);
outside = next*next;
}
}
private void iteratorStream(List<Integer> integers) {
integers.stream().forEach((ii) -> {
outside = ii*ii;
});
}
타이밍은 다음과 같습니다.밀리초 / 함수 / 목록 내 엔트리 수각 실행은 10^6 루프입니다.
1 10 100 1000 10000
iterator.forEach 27 116 959 8832 88958
for:each 53 171 1262 11164 111005
for with index 39 112 920 8577 89212
iterable.stream.forEach 255 324 1030 8519 88419
실험을 반복하면 소스코드 전체를 올렸습니다.이 답변을 편집하고 테스트한 시스템의 표기를 사용하여 결과를 추가하십시오.
MacBook Pro, 2.5GHz 인텔 Core i7, 16GB, MacOS 10.12 사용.6:
1 10 100 1000 10000
iterator.forEach 27 106 1047 8516 88044
for:each 46 143 1182 10548 101925
for with index 49 145 887 7614 81130
iterable.stream.forEach 393 397 1108 8908 88361
Java 8 핫스팟 VM - 3.4GHz 인텔 Xeon, 8 GB, Windows 10 Pro
1 10 100 1000 10000
iterator.forEach 30 115 928 8384 85911
for:each 40 125 1166 10804 108006
for with index 30 120 956 8247 81116
iterable.stream.forEach 260 237 1020 8401 84883
VM - 4Java 11 - 3.4 인텔 10 © Xeon, 8GB, Windows 10 Pro
, JDK (JDK)
1 10 100 1000 10000
iterator.forEach 20 104 940 8350 88918
for:each 50 140 991 8497 89873
for with index 37 140 945 8646 90402
iterable.stream.forEach 200 270 1054 8558 87449
Java 11 OpenJ9 VM - 3.4GHz 인텔 Xeon, 8 GB, Windows 10 Pro
및 , VMVM의 경우 JDK의 경우,
1 10 100 1000 10000
iterator.forEach 211 475 3499 33631 336108
for:each 200 375 2793 27249 272590
for with index 384 467 2718 26036 261408
iterable.stream.forEach 515 714 3096 26320 262786
Java 8 핫스팟 VM - 2.8GHz AMD, 64 GB, Windows Server 2016
1 10 100 1000 10000
iterator.forEach 95 192 2076 19269 198519
for:each 157 224 2492 25466 248494
for with index 140 368 2084 22294 207092
iterable.stream.forEach 946 687 2206 21697 238457
VM - 8Java 11 - 2.8 AMD, GB, Server GHz AMD, 64 GB, Windows Server 2016
, JDK (JDK)
1 10 100 1000 10000
iterator.forEach 72 269 1972 23157 229445
for:each 192 376 2114 24389 233544
for with index 165 424 2123 20853 220356
iterable.stream.forEach 921 660 2194 23840 204817
Java 11 OpenJ9 VM - 2.8GHz AMD, 64 GB, Windows Server 2016
및 , VMVM의 경우 JDK의 경우,
1 10 100 1000 10000
iterator.forEach 592 914 7232 59062 529497
for:each 477 1576 14706 129724 1190001
for with index 893 838 7265 74045 842927
iterable.stream.forEach 1359 1782 11869 104427 958584
선택하는 VM 구현에 따라 Hotspot/OpenJ9/등도 달라집니다.
두 사이에는 가 없습니다.최소한 개념적으로는Collection.forEach()
그냥 줄임말일 뿐이야
으로는, 「」라고 하는 일컬어지고 있습니다.stream()
버전에서는 오브젝트 작성으로 인해 오버헤드가 다소 증가하지만 실행 시간을 보면 오버헤드가 발생하지 않습니다.
구현 모두 '아,어,어,어,어,느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다느끼다.collection
내용을 한 번 인쇄하고 반복하는 동안 요소를 인쇄합니다.
Collection.forEach()는 컬렉션의 반복기(지정된 경우)를 사용합니다.즉, 항목의 처리 순서가 정해져 있습니다.반대로 Collection.stream().ForEach()의 처리순서는 정의되어 있지 않습니다.
대부분의 경우, 둘 중 어느 쪽을 선택하든 상관없습니다.병렬 스트림을 사용하면 스트림을 여러 스레드로 실행할 수 있으며 이러한 상황에서는 실행 순서가 정의되지 않습니다.Java는 Collectors.toList() 등의 터미널 조작을 호출하기 전에 모든 스레드를 완료해야 합니다.먼저 컬렉션에서 직접 Each()를 호출하고 다음으로 병렬 스트림에서 호출하는 예를 살펴보겠습니다.
list.forEach(System.out::print);
System.out.print(" ");
list.parallelStream().forEach(System.out::print);
코드를 여러 번 실행하면 list.forEach()는 삽입 순서대로 항목을 처리하는 반면 list.parallelStream()은 실행마다 다른 결과를 생성합니다.출력은 다음과 같습니다.
ABCD CDBA
또 다른 예는 다음과 같습니다.
ABCD DBCA
언급URL : https://stackoverflow.com/questions/23218874/what-is-difference-between-collection-stream-foreach-and-collection-foreach
'programing' 카테고리의 다른 글
Android 분할 문자열 (0) | 2022.08.27 |
---|---|
vue.js에서 새로 고치지 않고 페이지에서 데이터를 업데이트하는 방법 (0) | 2022.08.27 |
vuex-sync의 용도는 무엇입니까? (0) | 2022.08.27 |
Java에서 문자열 형식의 현재 타임스탬프를 가져오려면 어떻게 해야 합니까?"yyy.MM.dd.HH.mm.ss." (0) | 2022.08.27 |
다시 Vue.nextTick을 Vuex 변환에 사용하는 것이 관례입니까?뭔가 부서질까? (0) | 2022.08.27 |