2015-01-20 3 views
1

스트림 API를 사용하여 groupingBy ->counting 연산을 사용하여 수집 한 후 필터링하면 어떻게 발생 횟수 필터를 기반으로하는 항목이 포함됩니까?발생 횟수를 기준으로 항목을 필터링하는 방법은 무엇입니까?

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5) 
     .collect(groupingBy(n -> n, counting())); 

어떻게 난 단지 키 25를 포함하는이를 필터링 할 다음 감안할 때

?

다음을 사용할 수는 있지만 먼저 수집해야하는 대신 스트림을 계속 사용할 수 있기를 바랬습니다.

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5) 
     .collect(groupingBy(n -> n, counting())) 
     .entrySet().stream() 
     .filter(n -> n.getValue() > 1) 
     .collect(toMap(Entry::getKey, Entry::getValue)); 

답변

3

이미 본 값에 의존하는 작업을 위해지도 또는 유사한 데이터 구조를 구축 할 방법이 없습니다. 예를 들어 distinct과 동일합니다. 작업 체인 내에서 단계처럼 보이지만 내부적으로지도 (또는지도와 같은 구조)를 작성하지 않으면 작동하지 않습니다.

당신은 전체 것은

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5) 
    .collect(collectingAndThen(groupingBy(n -> n, counting()), 
     map -> map.entrySet().stream() 
     .filter(n -> n.getValue() > 1) 
     .collect(toMap(Entry::getKey, Entry::getValue)) 
    )); 

를 사용하여 단일 스트림 작업처럼 보일 수 있지만 그것이 작동하는 방식을 변경하지 않습니다. 발생하는 모든 값은 먼저 값의 다른 어커런스가 존재하지 않는다고 추론하기 위해 스트림의 끝까지 도달해야하기 때문에 먼저 기억해야합니다. 때때로 비 스트림 작업이보다 간결 보일 수 있습니다

참고 :

Map<Integer, Long> counts = Stream.of(1, 2, 2, 3, 4, 5, 5) 
    .collect(groupingBy(n -> n, HashMap::new, counting())); 
counts.values().removeIf(count -> count < 2); 

당신의 실제 수에 대한 걱정없이 (병렬 가능) Stream 내에서 항목 자체의 처리에 관심이 있다면 여기에 간단한 솔루션이 있습니다 :

ConcurrentHashMap<Integer,Integer> counts=new ConcurrentHashMap<>(); 
Stream.of(1, 2, 2, 3, 4, 5, 5) 
     .filter(i -> counts.merge(i, 1, Integer::sum)==2) 
     .forEach(System.out::println); 

이 기능을 사용하면 2 분의 1 초에 후속 작업을 적용 할 수 있습니다 일종의 D 항목 요구 프로세스 모든 항목 또는 스트림의 종료를 기다리는 않고 발생 등

+0

점이 구별하는 것이 되 parallel 실행 및/또는 단락 limit 또는 findAny 같은 조작으로 조화 된 병렬로 작동하며, 함수를 만족하는 첫 번째 인수를 받아들이는 개수를 유지하는 spliterator를 제공 할 수 있습니다 (예를 들어보다 큼). spliterator는 카운트를 수락하기 전에 모두를 방문해야하는 경우 제어하기위한 인수가 필요합니다. 스트림을 소트하면 (자), 각 수용은 스트림 파이프 라인으로 오브젝트를 곧 통과시킵니다. –

+1

그건 서면으로 질문 범위를 벗어납니다. 스트림에 * 정렬 된 * 속성이 없으며 질의에 표시된 작업은 어떤 경우에도 각 항목을 처리해야하는 발생 횟수에 따라지도에 결과를 수집하는 것과 같이 복잡한 구현으로 인해 어떠한 이익도 발생하지 않습니다 . – Holger

+0

간단한 예를 들어,지도에 수집하지 말았어야했는데, 내가 달성하려고 시도한 것을 강조하기 위해 사용했는데, 결과가 중요하지 않은지, spliterator가 업스트림을 정렬 할 필요가 없다는 것을 강조했습니다. 강조 표시 만하면 도움이 될 수 있습니다. 사용할 수있는 것이 없다고 생각합니다. 설명한대로 스플 뢰 네이터 구현을 시도해 볼 수 있습니다. –

관련 문제