가능한 해결 방법은 Stream
의 스플 리터 레이터를 래핑하는 Spliterator
을 직접 작성하는 것입니다. 이 Spliterator
은 줄 바꿈 된 spliterator로 전진하는 호출을 위임하고 많은 별개 요소의 계산 논리를 포함합니다.
이렇게하려면 서브 클래스 AbstractSpliterator
을 사용하고 우리 자신의 tryAdvance
논리를 제공 할 수 있습니다. 다음에서, 모든 요소는 세트에 추가됩니다. 해당 세트의 크기가 최대 값보다 커지거나 래핑 된 spliterator에 남아있는 요소가없는 경우을 반환하여 고려해야 할 요소가 없음을 나타냅니다. 별개의 요소에 도달하면이 작업이 중단됩니다.
Map<String, Long> m =
distinctLimit(Stream.of("a", "a", "b", "c", "d"), 3)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
및 출력은 즉 3 개별의 키와지도, {a=2, b=1, c=1}
을 예상 할 수 :
귀하의 예제 코드와
private static <T> Stream<T> distinctLimit(Stream<T> stream, int max) {
Spliterator<T> spltr = stream.spliterator();
Spliterator<T> res = new AbstractSpliterator<T>(spltr.estimateSize(), spltr.characteristics()) {
private Set<T> distincts = new HashSet<>();
private boolean stillGoing = true;
@Override
public boolean tryAdvance(Consumer<? super T> action) {
boolean hasRemaining = spltr.tryAdvance(elem -> {
distincts.add(elem);
if (distincts.size() > max) {
stillGoing = false;
} else {
action.accept(elem);
}
});
return hasRemaining && stillGoing;
}
};
return StreamSupport.stream(res, stream.isParallel()).onClose(stream::close);
}
, 당신은 할 것이다.
필터링 할 수 없습니까? – SamTebbs33
이렇게 할 수 있니? 허용되는지 확실하지 않습니다. Map m = Stream.of ("a", "a", "b", "c", "d") .limit (m.size() <3? Integer.MAX_VALUE : 3) . 콜렉터 (toMap (Function.identity(), 1, Integer :: sum)); –
nbokmans
* "방법이 있습니까?"* 네 자신의'toMap()'콜렉터를 작성하십시오. 그거 편리할까요? 원근법의 물질, 나는 짐작한다. – Andreas