에서 객체를 제공하는 Java 코드가 있습니다 items
. 다음을 기반으로 제한합니다 maxNumber
.
items.stream()
.map(this::myMapper)
.filter(item -> item != null)
.limit(maxNumber)
.collect(Collectors.toList());
제대로 작동하지만 문제는 다음과 같습니다. 제한 시간을 건너 뛸 수있는 방법이 maxNumber == 0
있습니까?
나는 이것을 할 수 있다는 것을 안다.
if (maxNumber == 0) {
items.stream()
.map(this::myMapper)
.filter(item -> item != null)
.collect(Collectors.toList());
} else {
items.stream()
.map(this::myMapper)
.filter(item -> item != null)
.limit(maxNumber)
.collect(Collectors.toList());
}
그러나 더 좋은 방법이있을 수 있습니다.
답변
나는 그것을 생각
.limit(maxNumber == 0 ? Long.MAX_VALUE : maxNumber)
2 ^ 63-1 개 이상의 요소가있는 스트림을 처리 할 가능성이 높지 않으므로 트릭을 수행합니다 …
적어도 이것에 대한 병렬 스트림에주의하십시오 … API 문서의 메모에 따르면
API 참고 :
limit()
일반적으로 순차 스트림 파이프 라인에서 저렴한 작업 이지만 , 주문 된 병렬 파이프 라인에서, 특히 maxSize 값이 큰 경우 비용이 많이들 수 있습니다 .
답변
아니요, 스트림 파이프 라인은 파이프 라인의 일부 를 실제로 건너 뛸 수 없으므로 단계 내에서 조건부 논리 limit()
를 사용하고 파이프 라인에 항상 포함 하거나 스트림을 파트에 스트림을 작성해야합니다. 질문의 if / else보다 조금 더 읽기 쉬운 (IMHO)
Stream<Item> s = items.stream()
.map(this::myMapper)
.filter(Objects::nonNull);
if(maxNumber > 0) {
s = s.limit(maxNumber);
}
List<Item> l = s.collect(Collectors.toList());
여기와 같은 간단한 경우에는 큰 차이가 없지만 일반 코드 컬렉션에서 메서드를 통해 전달되고 스트림으로 변환 된 다음 컬렉션으로 다시 돌아가는 경우가 종종 있습니다. 이러한 경우 실제로 필요할 때까지 스트림을 여러 파트로 작업하는 것이 좋습니다 collect()
.