콜렉터 이 사용될 수있다.
- 두 가지 범주의 경우
Collectors.partitioningBy()
factory를 사용하십시오 .
이렇게하면 Map
from Boolean
을 만들고를 기준으로 List
항목을 하나 또는 다른 목록에 넣습니다 Predicate
.
참고 : 스트림 전체를 소비해야하므로 무한 스트림에서는 작동하지 않습니다. 스트림은 어쨌든 소비되기 때문에이 방법을 사용하면 메모리로 새로운 스트림을 만드는 대신 단순히 목록에 넣습니다. 출력으로 스트림이 필요한 경우 언제든지 해당 목록을 스트리밍 할 수 있습니다.
또한 사용자가 제공 한 헤드 전용 예제에서도 반복자가 필요하지 않습니다.
Random r = new Random();
Map<Boolean, List<String>> groups = stream
.collect(Collectors.partitioningBy(x -> r.nextBoolean()));
System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());
- 더 많은 카테고리는
Collectors.groupingBy()
공장을 사용하십시오 .
Map<Object, List<String>> groups = stream
.collect(Collectors.groupingBy(x -> r.nextInt(3)));
System.out.println(groups.get(0).size());
System.out.println(groups.get(1).size());
System.out.println(groups.get(2).size());
스트림이 아닌 Stream
기본 스트림 중 하나 인 IntStream
경우이 .collect(Collectors)
방법을 사용할 수 없습니다. 컬렉터 팩토리없이 수동으로 수행해야합니다. 구현은 다음과 같습니다.
[2020-04-16 이후의 예제 2.0]
IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(100000).parallel();
IntPredicate predicate = ignored -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(
() -> Map.of(false, new ArrayList<>(100000),
true , new ArrayList<>(100000)),
(map, value) -> map.get(predicate.test(value)).add(value),
(map1, map2) -> {
map1.get(false).addAll(map2.get(false));
map1.get(true ).addAll(map2.get(true ));
});
이 예제에서는 초기 컬렉션의 전체 크기로 ArrayLists를 초기화합니다 (이것이 전혀 알려지지 않은 경우). 이렇게하면 최악의 시나리오에서도 크기 조정 이벤트를 방지 할 수 있지만 2 * N * T 공간을 잠재적으로 증가시킬 수 있습니다 (N = 초기 요소 수, T = 스레드 수). 속도를 위해 공간을 절충하기 위해 한 파티션에서 예상되는 가장 많은 수의 요소 (일반적으로 균형 잡힌 분할의 경우 N / 2 이상)와 같이 공간을 그대로 두거나 가장 잘 교육 된 추측을 사용할 수 있습니다.
Java 9 메소드를 사용하여 다른 사람을 화나게하지 않기를 바랍니다. Java 8 버전의 경우 편집 히스토리를보십시오.
Stream
배수Stream
의 중간 변환없이 나는이 질문에 도달 사람들이 실제로 그렇게 관계없이 마크의 대답은 이러한 제약 조건의 달성하기 위해 방법을 찾고 있다고 생각하지만. 이는 제목의 질문 이 설명 의 질문과 동일하지 않기 때문일 수 있습니다 .