[collections] Java 8의 java.util.stream.Stream에서 목록 검색

컬렉션을 쉽게 필터링하기 위해 Java 8 람다로 놀고있었습니다. 그러나 나는 동일한 진술 내에서 결과를 새로운 목록으로 검색하는 간결한 방법을 찾지 못했습니다. 지금까지 가장 간결한 접근 방식은 다음과 같습니다.

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);

그물에있는 예제는 새로운 결과 목록을 생성하지 않고 멈추기 때문에 내 질문에 대답하지 못했습니다. 더 간결한 방법이 있어야합니다. 나는이 것을 예상했을 것이다 Stream클래스 등의 방법이있다 toList(), toSet()

targetLongList세 번째 줄 에서 변수 를 직접 할당 할 수 있는 방법이 있습니까?



답변

스트림이 순차적으로 유지되는 경우 가장 간단한 방법 일 수 있습니다 forEach.

[나중에 편집 : sequence ()에 대한 호출이 필요한 이유 forEach(targetLongList::add)는 스트림이 병렬 인 경우 코드 ( )가 고르지 않기 때문 입니다. 그럼에도 불구하고, 그것은 forEach명백히 비결정론 적이며 의도 된 효과를 달성하지 못할 것 입니다. 순차 스트림에서도 요소 처리 순서가 보장되지는 않습니다. forEachOrdered올바른 주문을 위해 사용해야 합니다. Stream API 디자이너의 의도는 아래와 같이이 상황에서 수집기를 사용하는 것입니다.]

대안은

targetLongList = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(Collectors.toList());


답변

업데이트 :

또 다른 방법은 다음을 사용하는 것입니다 Collectors.toList.

targetLongList =
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toList());

이전 솔루션 :

또 다른 방법은 다음을 사용하는 것입니다 Collectors.toCollection.

targetLongList =
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toCollection(ArrayList::new));


답변

필자가 원하는 ArrayList때에 수집기를 반환하는 util 메소드를 사용하고 싶습니다.

사용하는 솔루션 Collectors.toCollection(ArrayList::new)이 이러한 일반적인 작업에는 너무 시끄럽다고 생각합니다 .

예:

ArrayList<Long> result = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(toArrayList());

public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
    return Collectors.toCollection(ArrayList::new);
}

이 답변을 통해 사용자 지정 수집기를 만들고 사용하는 것이 얼마나 간단한 지 보여주고 싶습니다. 이는 일반적으로 매우 유용합니다.


답변

프리미티브 배열이있는 경우 Eclipse Collections 에서 사용 가능한 프리미티브 콜렉션을 사용할 수 있습니다 .

LongList sourceLongList = LongLists.mutable.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
LongList targetLongList = sourceLongList.select(l -> l > 100);

sourceLongList를 List다음 에서 변경할 수없는 경우 :

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList =
    ListAdapter.adapt(sourceLongList).select(l -> l > 100, new ArrayList<>());

사용하려는 경우 LongStream:

long[] sourceLongs = new long[]{1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L};
LongList targetList =
    LongStream.of(sourceLongs)
    .filter(l -> l > 100)
    .collect(LongArrayList::new, LongArrayList::add, LongArrayList::addAll);

참고 : 저는 Eclipse Collections에 기고자입니다.


답변

좀 더 효율적인 방법 (소스 목록 작성 및 필터에 의한 자동 우편함 제거) :

List<Long> targetLongList = LongStream.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L)
    .filter(l -> l > 100)
    .boxed()
    .collect(Collectors.toList());


답변

collect(Collectors.toList());

모든 스트림을 목록으로 변환하는 데 사용할 수있는 호출입니다.

보다 구체적으로 :

    List<String> myList = stream.collect(Collectors.toList()); 

에서:

https://www.geeksforgeeks.org/collectors-tolist-method-in-java-with-examples/


답변

써드 파티 라이브러리를 사용하지 않아도 AOL의 cyclops-react lib (제공자 인 공개)에는 List를 포함한 모든 JDK 콜렉션 유형에 대한 확장이 있습니다 . ListX 인터페이스는 java.util.List를 확장하고 필터를 포함하여 많은 유용한 연산자를 추가합니다.

간단히 쓸 수 있습니다.

ListX<Long> sourceLongList = ListX.of(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
ListX<Long> targetLongList = sourceLongList.filter(l -> l > 100);

ListX는 기존 List에서 생성 할 수도 있습니다 (ListX.fromIterable을 통해)