首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8集合合并列表

Java 8集合合并列表
EN

Stack Overflow用户
提问于 2016-01-29 10:49:29
回答 5查看 257关注 0票数 3

我正在尝试使用员工姓名合并集合。

我有一个带有List<Employee(name, List<Address(String)>)>MainDTO

EmployeeString nameList Address AddressString

代码语言:javascript
复制
MainDTO -> List<Employee> empList;
Employee-> String name, List<String>

我有输入数据:

代码语言:javascript
复制
( ("emp1",[("KY"),"("NY")]),
  ("em2",[("KY"),"("NY")]),
  ("emp1",[("MN"),"("FL")]),
  ("emp1",[("TN"),"("AZ")])
)

输出将为:

代码语言:javascript
复制
( ("emp1",[("KY"),"("NY"),("MN"),"("FL"),("TN"),"("AZ")]),
  ("em2",[("KY"),"("NY")])
)

使用java8或java7对这些数据进行排序的最佳方法。

EN

回答 5

Stack Overflow用户

发布于 2016-01-29 11:32:44

如果可以选择Java9,则可以使用flatMapping

代码语言:javascript
复制
Map<String, List<String>> addressesByEmployeeName = empList
        .stream()
        .collect(groupingBy(
                Employee::getName, flatMapping(
                        e -> e.getAddresses().stream(),
                        toList())));

但我有一种奇怪的感觉,Java 9不是一个选择。

票数 5
EN

Stack Overflow用户

发布于 2016-01-30 03:10:13

shmosel's answer很好,因为它充分利用了新的JDK9 flatMapping收集器。如果不选择JDK 9,那么在JDK 8中也可以做一些类似的事情,尽管有点复杂。它在流中执行平面映射操作,生成员工姓名和地址对的流。我不会创建特殊的pair类,而是使用AbstractMap.SimpleEntry

基本思想是流式传输员工列表,并将其平面映射为成对的(姓名、地址)流。完成此操作后,将它们收集到映射中,按名称分组,并将地址收集到每个组的列表中。下面是实现这一点的代码:

代码语言:javascript
复制
import static java.util.AbstractMap.SimpleEntry;
import static java.util.Map.Entry;
import static java.util.stream.Collectors.*;

Map<String, List<String>> mergedMap =
    empList.stream()
           .flatMap(emp -> emp.getAddresses().stream().map(
                        addr -> new SimpleEntry<>(emp.getName(), addr)))
           .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList())));

这会产生一个Map。如果您想要从这些条目创建Employee对象,您可以通过流式传输这些条目来创建它们:

代码语言:javascript
复制
List<Employee> mergedEmps =
    mergedMap.entrySet().stream()
             .map(entry -> new Employee(entry.getKey(), entry.getValue()))
             .collect(toList());

创建map entry对象并从中提取数据有些麻烦,但并不可怕。如果您愿意,可以将这里的一些习惯用法提取到实用方法中,以使事情更简洁。

票数 2
EN

Stack Overflow用户

发布于 2016-01-30 04:31:24

如果您使用具有多贴图的库(如Eclipse Collections ),这将变得容易得多。

代码语言:javascript
复制
ListIterable<Employee> empList = ...;
MutableSortedSetMultimap<String, String> addressesByEmployeeName =
    new TreeSortedSetMultimap<>();
empList.each(e -> e.getAddresses().each(a -> addressesByEmployeeName.put(e.getName(), a)));

如果empList和地址列表不能从List更改为ListIterable,那么您可以使用ListAdapter使其正常工作。

代码语言:javascript
复制
ListAdapter.adapt(empList).each(
    e -> ListAdapter.adapt(e.getAddresses()).each(
        a -> addressesByEmployeeName.put(e.getName(), a)));

由于这种模式比较常见,我们可以将RichIterable.toMultimap()添加到库中。那么这个例子就可以归结为一行代码。

代码语言:javascript
复制
MutableListMultimap<String, String> addressesByEmployeeName =
    empList.toMultimap(Employee::getName, Employee::getAddresses);

注意:我是Eclipse Collections的提交者。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35076034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档