Java 8 获取列表中的所有元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35495906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 get all elements in list
提问by tsingh
I have a List of Objects where each object that returns List<String>
.
How can I use Java 8 streams to get only one List<String>
?
我有一个对象列表,其中每个返回List<String>
. 如何使用 Java 8 流只获得一个List<String>
?
Contact
class has the following method;
Contact
类有以下方法;
public List<String> getSharedFriendsIds() {
return sharedFriendsIds;
}
And I have
我有
List<Contact> contactsList;
What I was trying was
我正在尝试的是
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.sequential()
.collect(Collectors.toList());
But above line is not returning List<String>
but rather List<List<String>>
which is not what I want.
但上面的线没有返回 List<String>
,而是 List<List<String>>
这不是我想要的。
回答by bur?quete
You should use .flatMap()
to create a single list from the sharedFriendsIds
list that is contained in each Contact
object from the main list contactsList
. Please check;
您应该使用从主列表的每个对象中包含.flatMap()
的sharedFriendsIds
列表创建单个Contact
列表contactsList
。请检查;
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.sorted().collect(Collectors.toList());
The .filter()
call is for the case when there is any Contact
with sharedFriendsIds == null
in the list, since that would cause NPE
in the next line, we ought to filter those out. There are other ways to achieve that like;
该.filter()
调用适用于列表中有任何Contact
with的情况sharedFriendsIds == null
,因为这会导致NPE
下一行,我们应该将它们过滤掉。还有其他方法可以实现这一点;
- Optional
—— Optional
List<String> sharedContacts = contactsList.stream()
.flatMap(contacts -> Optional.ofNullable(contacts.getSharedFriendsIds())
.map(Collection::stream).orElseGet(Stream::empty))
.sorted().collect(Collectors.toList());
Where the filtering of null `sharedFriendsIds` are done in such a way that
they are absorbed into the `flatMap` logic as empty streams.
- emptyIfNull()
—— emptyIfNull()
You can include collections dependency from apache.commons
and use CollectionUtils.emptyIfNull
method as follows;
您可以按如下方式包含来自apache.commons
和使用CollectionUtils.emptyIfNull
方法的集合依赖项;
public static <T> Stream<T> collectionAsStream(Collection<T> collection) {
return emptyIfNull(collection).stream();
}
then call this from original stream like;
然后从原始流中调用它;
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.flatMap(Foo::collectionAsStream)
.sorted().collect(Collectors.toList());
Also you used .sequential
for the sort logic, I guess, you should've used .sorted
method, since sequential is for triggering non-parallel usage, which is already the default configuration of a Stream
.
您还用于.sequential
排序逻辑,我想,您应该使用.sorted
方法,因为顺序用于触发非并行使用,这已经是Stream
.
回答by dmitryvinn
There is no reason to use .sequential()
here, streams are sequential by default.
没有理由在.sequential()
这里使用,默认情况下流是顺序的。
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toList());
In natural order;
按自然顺序;
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.sorted().collect(Collectors.toList());
回答by Federico Peralta Schaffner
A pattern I've found very useful is to let the parent class (in this case the Contact
class) create and return the streams of children objects (in this case the share friends ids):
我发现一个非常有用的模式是让父类(在本例中为Contact
类)创建并返回子对象流(在本例中为共享朋友 ID):
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 the method that returns the stream as the attribute being streamed. This method already contains the null-check.
约定是将返回流的方法命名为正在流式传输的属性。此方法已包含空检查。
Then, getting the shared friends ids for all contacts is much easier:
然后,获取所有联系人的共享好友 ID 就容易多了:
List<String> sharedContacts = contactsList.stream()
.flatMap(Contact::sharedFriendsIds)
.collect(Collectors.toList());
You need to use flatMap()
in order to flattenthe elements of the child list into a single list, otherwise you'd get a list of streams.
您需要使用flatMap()
以将子列表的元素展平为单个列表,否则您将获得一个流列表。
Note 1: you don't need to use sequential()
, since using stream()
on the list of contacts already returns a sequential stream.
注意 1:您不需要使用sequential()
,因为stream()
在联系人列表上使用已经返回一个顺序流。
Note 2: if you want the final list to be sorted, then you should use sorted()
on the stream:
注意 2:如果您希望对最终列表进行排序,那么您应该sorted()
在流上使用:
List<String> sharedContacts = contactsList.stream()
.flatMap(Contact::sharedFriendsIds)
.sorted().collect(Collectors.toList());