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


19

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

그러나 더 좋은 방법이있을 수 있습니다.

답변:


15

나는 그것을 생각

.limit(maxNumber == 0 ? Long.MAX_VALUE : maxNumber)

2 ^ 63-1 개 이상의 요소가있는 스트림을 처리 할 가능성이 높지 않으므로 트릭을 수행합니다 ...

적어도 이것에 대한 병렬 스트림에주의하십시오 ... API 문서의 메모에 따르면

API 참고 : limit()일반적으로 순차 스트림 파이프 라인에서 저렴한 작업 이지만 , 주문 된 병렬 파이프 라인에서, 특히 maxSize 값이 큰 경우 비용이 많이들 수 있습니다 .


그래, 그 트릭을했다, 감사합니다!
randomuser1

20

아니요, 스트림 파이프 라인은 파이프 라인의 일부 를 실제로 건너 뛸 수 없으므로 단계 내에서 조건부 논리 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().

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.