Java 8获取列表

时间:2016-02-19 01:49:01

标签: java java-8 java-stream

我有一个对象列表,其中每个对象返回List<String>。 如何使用Java 8流只获得一个List<String>

Contact类有以下方法;

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

我有

List<Contact> contactsList;

我在尝试的是

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

但是上面的行不会返回List<String>而是返回List<List<String>>这不是我想要的。

3 个答案:

答案 0 :(得分:11)

您应该使用.flatMap()从主列表sharedFriendsIds中的每个Contact对象中包含的contactsList列表创建单个列表。请检查以下内容;

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

.filter()调用适用于列表中与sharedFriendsIds == null有任何联系的情况,因为这会在下一行中导致NPE,我们应该将其过滤掉。还有其他方法可以实现这一点;

List<String> sharedContacts = contactsList.stream()
        .flatMap(contacts -> Optional.ofNullable(contacts.getSharedFriendsIds())
                .map(List::stream).orElseGet(Stream::empty))
        .sorted().collect(Collectors.toList());

对null sharedFriendsIds的过滤以这样的方式完成,即它们作为空流被吸收到flatMap逻辑中。

你也使用.sequential作为排序逻辑,我想你应该使用.sorted方法,因为顺序用于触发非并行使用,这已经是默认配置默认Stream

答案 1 :(得分:5)

此处没有理由使用.sequential(),默认情况下,流是顺序的。

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

按自然顺序;

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

答案 2 :(得分:2)

我发现非常有用的模式是让父类(在本例中为Contact类)创建并返回子对象流(在本例中是共享朋友ID): / p>

public class Contact {

    private List<String> sharedFriendsIds;

    public Stream<String> sharedFriendsIds() {
        return sharedFriendsIds == null ? Stream.empty() : sharedFriendsIds.stream();
    }

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

约定是将返回流的方法命名为要流式传输的属性。此方法已包含空检查。

然后,为所有联系人获取共享的朋友ID更容易:

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

您需要使用flatMap() 将子列表的元素展平到一个列表中,否则您将获得一个流列表。

注1:您不需要使用sequential(),因为在联系人列表中使用stream()已经返回了顺序流。

注意2:如果您希望对最终列表进行排序,那么您应该在流上使用sorted()

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