Programing

Java 8-지루한 수집 방법 생략

crosscheck 2020. 12. 30. 19:02
반응형

Java 8-지루한 수집 방법 생략


Java 8 스트림 API는 매우 좋은 기능이며 절대적으로 좋아합니다. 제 신경을 쓰는 한 가지는 입력을 컬렉션으로, 출력을 컬렉션으로 원한다는 것입니다. 결과는 항상 호출 stream()하고 collect()메쏘드해야한다는 것입니다.

collection.stream().filter(p->p.isCorrect()).collect(Collectors.toList());

스트림을 건너 뛰고 컬렉션에서 직접 작업 할 수있는 Java API가 linq있습니까 (예 : C #?) :

collection.filter(p->p.isCorrect)

컬렉션 작업을하려는 경우 Guava의 FluentIterable좋습니다 !

예 (첫 VIP 고객 10 명의 ID 가져 오기) :

FluentIterable
       .from(customers)
       .filter(customer -> customer.isVIP())
       .transform(Client::getId)
       .limit(10);

예, 다음을 사용합니다 Collection#removeIf(Predicate).

주어진 술어를 만족하는이 콜렉션의 모든 요소를 ​​제거합니다.

새 컬렉션을 반환하지 않고 지정된 컬렉션을 변경합니다. 그러나 컬렉션의 복사본을 만들고 수정할 수 있습니다. 또한 술어는 필터로 작동하려면 부정해야합니다.

public static <E> Collection<E> getFilteredCollection(Collection<E> unfiltered,
                                                      Predicate<? super E> filter) {
    List<E> copyList = new ArrayList<>(unfiltered);

    // removeIf takes the negation of filter 
    copyList.removeIf(e -> { return !filter.test(e);});  

    return copyList;
}

그러나 @Holger가 주석에서 제안했듯이 코드에서이 유틸리티 메서드를 정의하고 필터링 된 컬렉션을 가져 오는 데 필요한 모든 곳에서 사용하는 경우 collect해당 유틸리티 메서드에 호출을 위임하면 됩니다. 그러면 발신자 코드가 더 간결 해집니다.

public static <E> Collection<E> getFilteredCollection(Collection<E> unfiltered,
                                                      Predicate<? super E> filter) {
   return unfiltered.stream()
                    .filter(filter)
                    .collect(Collectors.toList());
}

StreamEx 사용을 좋아할 수도 있습니다.

StreamEx.of(collection).filter(PClass::isCorrect).toList();

이것은 불변성을 유지하면서 약간 더 짧다는 장점이 있습니다.


Streams에는 잘 정의 된 아키텍처가 포함되어 있으므로 . 이 길을 시작하기 전에 그것에 대해 읽어 보는 것이 좋습니다.

그러나 그 코드를 래핑하는 유사한 스트림 인터페이스를 구현하는 컬렉션을 구현하는 것은 어떨까요?

public class StreamableCollection implements Collection, Stream {
...
}

그런 다음 사용 사례에 대해 까다로운 가정을 할 수 있습니다. 컬렉션 인터페이스에서 스트림을 열 수는 있지만 바로 들어가서 내부에서 스트림의 열기를 처리 할 수도 있습니다.

    streamableCollection cs = new streamableCollection();
    cs.filter();
    cs.stream();

IDE는 모든 것을 바로 구현할 수 있기를 바랍니다. 모든 것을 기본 구현으로 되 돌리면됩니다.


원본 컬렉션을 수정하지 않고 필터링 된보기가 필요한 경우 Guava의 Collections2.filter().


나는 또한 Stream API가 좋지만 짧은 작업에는 장황하다고 생각합니다. 몇 가지 프로젝트에서 이러한 유틸리티 방법을 사용했습니다.

import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Functions {

    public static <T,V> List<V> map(final List<T> in, final Function<T, V> function) {
        return in == null ? null : map(in.stream(), function);
    }

    public static <T,V> List<V> map(final Stream<T> in, final Function<T, V> function) {
        return in == null ? null : in
            .map(function)
            .collect(Collectors.toList());
    }

    public static <T> List<T> filter(final List<T> in, final Predicate<T> predicate) {
        return in == null ? null : filter(in.stream(), predicate);
    }

    public static <T> List<T> filter(final Stream<T> in, final Predicate<T> predicate) {
        return in == null ? null : in
            .filter(predicate)
            .collect(Collectors.toList());
    }
}

예를 들어 할 수 있습니다.

List<String> wrapped = Functions.map(myList, each -> "[" + each + "]");

일반적으로 메서드도 정적 가져옵니다.


If you are open to using a third party library, you could use Eclipse Collections which has rich APIs directly available under collections. Your example can be written as below with Eclipse Collections.

collection.select(p->p.isCorrect)
collection.select(MyClass::isCorrect)

Note: I am a committer for Eclipse Collections.


You might try this, from the guava library. It seems a little less cluttered than the Stream approach.

 ImmutableList.copyOf(Iterables.filter(collection, MyClass::isCorrect));

See Google Collections (Guava Libraries): ImmutableSet/List/Map and Filtering for a discussion on the technique.


Yes, there are several libraries that address Java 8's stream verbosity. An incomplete list:

My preference goes with jOOL. I've been using it in my last projects. The others I know but I didn't really use so I can't give you an impression.

Your example with jOOL would be:

Seq.seq(collection).filter(p->p.isCorrect()).toList();

With cyclops-react you have a number of options.

We can make use of Lazy Extended Collections

  CollectionX<String> collection = ListX.of("hello","world");
  CollectionX<String> filtered = collection.filter(p->p.isCorrect());

There is support for mutable, immutable and persistent extended collections. Functional operations on collections are lazy (i.e. behave like replayable Streams) and are materialized only on first access.

We can make use of a powerful extened Stream type

  ReactiveSeq.fromIterable(collection)
             .filter(p->p.isCorrect())
             .toList();

[Disclosure I am the lead developer of cyclops-react]

ReferenceURL : https://stackoverflow.com/questions/37124120/java-8-omitting-tedious-collect-method

반응형