[java] 숫자가 0 일 때 스트림으로 limit (number) 호출을 건너 뛰려면 어떻게해야합니까?

에서 객체를 제공하는 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().


답변