Java 8 gets all the items in a list

I have a list of objects, each of which returns a List<String> . How can I use Java 8 threads to get a single List<String> ?

Contact class has the following method:

 public List<String> getSharedFriendsIds() { return sharedFriendsIds; } 

And I have

 List<Contact> contactsList; 

What I tried was

 List<String> sharedContacts = contactsList.stream() .map(Contact::getSharedFriendsIds) .sequential() .collect(Collectors.toList()); 

But the above line does not return List<String> , but rather List<List<String>> , which is not what I want.

+7
java java-8 java-stream
source share
3 answers

You must use .flatMap() to create a single list from separate lists contained in each Contact object in the main contactsList list.

 List<String> sharedContacts = contactsList.stream() .filter(contacts -> contacts.getSharedFriendsIds() != null) .flatMap(contacts -> contacts.getSharedFriendsIds().stream()) .sorted().collect(Collectors.toList()); 

Check the updated snippet above with an additional .filter in case there are objects in the list with sharedFriendsIds == null . Also, you used .sequential for the sorting logic, I think you should use the .sorted method, since it is serial for non-parallel use, which is already the default configuration.

+9
source share

There is no reason to use .sequential() here, streams are sequential by default.

 List<String> sharedContacts = contactsList.stream() .map(Contact::getSharedFriendsIds) .filter(Objects::nonNull) .flatMap(Collection::stream) .collect(Collectors.toList()); 

In kind

 List<String> sharedContacts = contactsList.stream() .map(Contact::getSharedFriendsIds) .filter(Objects::nonNull) .flatMap(Collection::stream) .sorted() .collect(Collectors.toList()); 
+4
source share

I found a template very useful to allow the parent class (in this case the Contact class) to create and return streams of child objects (in this case, share friends tags):

 public class Contact { private List<String> sharedFriendsIds; public Stream<String> sharedFriendsIds() { return sharedFriendsIds == null ? Stream.empty() : sharedFriendsIds.stream(); } public List<String> getSharedFriendsIds() { return sharedFriendsIds; } } 

The convention is to name a method that returns a stream as the stream passed by the attribute. This method already contains a null check.

Then getting common friends ids for all contacts is much simpler:

 List<String> sharedContacts = contactsList.stream() .flatMap(Contact::sharedFriendsIds) .collect(Collectors.toList()); 

You need to use flatMap() to smooth the elements of the child list into a single list, otherwise you will get a list of threads.

Note 1: you do not need to use sequential() since using stream() in your contact list already returns a serial stream.

Note 2: if you want the final list to be sorted, you must use sorted() in the stream:

 List<String> sharedContacts = contactsList.stream() .flatMap(Contact::sharedFriendsIds) .sorted() .collect(Collectors.toList()); 
+3
source share

All Articles