How to use collect call in Java 8?

后端 未结 2 1051
梦谈多话
梦谈多话 2021-02-12 09:11

Lets say we have this boring piece of code that we all had to use:

ArrayList ids = new ArrayList();
for (MyObj obj : myList){
    ids.add         


        
相关标签:
2条回答
  • 2021-02-12 10:01

    I use a lot of collector blocks where I create an empty Array and fill it using a loop so I decided I need a utility class of my own not to write the same lines again ad again, here it is:

    public class Collections {
    
        public static <T, O> List<T> collect(Set<O> items, Function<? super O, ? extends T> mapper) {
    
        return items.stream().map(mapper).collect(Collectors.toCollection(ArrayList::new));
    }
    

    }

    and use it like this

    List<Product> prods = Collections.collect(basket.getOrderItems(), OrderItem::getProduct);
    

    or like this

    List<Long> prods = Collections.collect(basket.getOrderItems(), (item)->item.getProduct().getId());
    

    Though it might look like much more easier to read, it seems streams are a little slower in these kind of scenarios, look here

    0 讨论(0)
  • 2021-02-12 10:11

    The issue is that Collectors.toList, not surprisingly, returns a List<T>. Not an ArrayList.

    List<Long> ids = remove.stream()
            .map(MyObj::getId)
            .collect(Collectors.toList());
    

    Program to the interface.

    From the documentation:

    Returns a Collector that accumulates the input elements into a new List. There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more control over the returned List is required, use toCollection(Supplier).

    Emphasis mine - you cannot even assume that the List returned is mutable, let alone that it is of a specific class. If you want an ArrayList:

    ArrayList<Long> ids = remove.stream()
            .map(MyObj::getId)
            .collect(Collectors.toCollection(ArrayList::new));
    

    Note also, that it is customary to use import static with the Java 8 Stream API so adding:

    import static java.util.stream.Collectors.toCollection;
    

    (I hate starred import static, it does nothing but pollute the namespace and add confusion. But selective import static, especially with the Java 8 utility classes, can greatly reduce redundant code)

    Would result in:

    ArrayList<Long> ids = remove.stream()
            .map(MyObj::getId)
            .collect(toCollection(ArrayList::new));
    
    0 讨论(0)
提交回复
热议问题