Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continue mapping after stream collect

How do I continue the stream mapping after collect:

public Bus createBus(List<String> passengers) {
   return passengers.stream()
             .map(name -> new Person(name))
             .collect(Collectors.toList())
             .map(personList -> new Bus(personList))
}

Above obviously does not work. How to make it work elegantly without using any variables in the method body?

Edit: Constructor is Bus(List persons).

like image 763
Raipe Avatar asked Sep 18 '18 08:09

Raipe


People also ask

Does stream map maintain order?

A parallel stream is performed one or more elements at a time. Thus the map() would preserve the encounter of the stream order but not the original List's order.

How do I collect a stream map?

Method 1: Using Collectors.toMap() Function The Collectors. toMap() method takes two parameters as the input: KeyMapper: This function is used for extracting keys of the Map from stream value. ValueMapper: This function used for extracting the values of the map for the given key.

Does stream collect return new list?

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) . The original list remains unaffected. Thanks!

Which is the correct way of obtaining a stream from the collection?

You obtain a stream from a collection by calling the stream() method of the given collection. Here is an example of obtaining a stream from a collection: List<String> items = new ArrayList<String>(); items.


3 Answers

You could use the Collector from Collectors.collectingAndThen to perform an additional finishing transformation :

public Bus createBus(List<String> passengers) {
    return passengers.stream()
            .map(name -> new Person(name))
            .collect(Collectors
                    .collectingAndThen(Collectors.toList(), Bus::new));
}
like image 138
Matthieu Gabin Avatar answered Oct 21 '22 16:10

Matthieu Gabin


map will iterate over each Person in your list. Your Bus, instead, seems to need the whole list as a parameter. As it is, you try to create a new Bus for each name in the passengers list.

You can either pass the collected list directly to the constructor:

public Bus createBus(List<String> passengers) {
   return new Bus(passengers.stream()
             .map(name -> new Person(name))
             .collect(Collectors.toList()));
}

or store it in a variable (which I think is clearer):

public Bus createBus(List<String> passengers) {
   List<Person> persons = passengers.stream()
             .map(name -> new Person(name))
             .collect(Collectors.toList());
   return new Bus(persons);
}
like image 1
Thomas Francois Avatar answered Oct 21 '22 17:10

Thomas Francois


Since collect returns a collection, you need to open a new stream on the new collected list:

 list.stream().map(name -> new Person(name))
         .collect(Collectors.toList())
         .stream()....

or simply remove the collect: list.stream().map(name -> new Person(name)).map(...). That would make much more sense in your case

like image 1
ItFreak Avatar answered Oct 21 '22 17:10

ItFreak