Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8集合合并列表_Java_Collections_Java 8 - Fatal编程技术网

Java8集合合并列表

Java8集合合并列表,java,collections,java-8,Java,Collections,Java 8,我正在尝试使用员工姓名合并集合 我有一个MainDTO,它有列表 员工拥有字符串名称和列表地址 地址是一个字符串 MainDTO -> List<Employee> empList; Employee-> String name, List<String> 输出将是: ( ("emp1",[("KY"),"("NY"),("MN"),"("FL"),("TN"),"("AZ")]), ("em2",[("KY"),"("NY")]) ) 使用java

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

我有一个
MainDTO
,它有
列表

员工
拥有
字符串名称
列表地址
地址
是一个
字符串

MainDTO -> List<Employee> empList;
Employee-> String name, List<String>
输出将是:

( ("emp1",[("KY"),"("NY"),("MN"),"("FL"),("TN"),"("AZ")]),
  ("em2",[("KY"),"("NY")])
)

使用java 8或java 7对这些数据进行排序的任何最佳方法。

这是解决问题的一个可能的解决方案-如果要避免重复值,请使用Set;否则,请使用列表:

public static void main(String[]args){
    final List<Map.Entry<String, List<String>>> inputData = new ArrayList<>();
    inputData.add(new AbstractMap.SimpleEntry<String, 
            List<String>>("emp1", Arrays.asList("KY","NY")));
    inputData.add(new AbstractMap.SimpleEntry<String, 
            List<String>>("emp2", Arrays.asList("KY","NY")));
    inputData.add(new AbstractMap.SimpleEntry<String, 
            List<String>>("emp1", Arrays.asList("MN","FL")));
    inputData.add(new AbstractMap.SimpleEntry<String, 
            List<String>>("emp1", Arrays.asList("MN","FL")));

    //If you do not care about duplicates - use List
    final Map<String,List<String>> possibleWithDuplicatesData = 
            inputData.stream()
            .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> new ArrayList<String>()));     
    inputData.stream()
    .filter(entry -> possibleWithDuplicatesData.containsKey(entry.getKey()))
    .forEach(entry->
    possibleWithDuplicatesData.get(entry.getKey()).addAll(entry.getValue()));

    //If you want to avoid duplicates - use Set
            final Map<String,Set<String>> noDuplicatesData = 
                    inputData.stream()
                    .collect(Collectors.toMap(Map.Entry::getKey,
                            entry -> new HashSet<String>()));       
            inputData.stream()
            .filter(entry -> noDuplicatesData.containsKey(entry.getKey()))
            .forEach(entry->
            noDuplicatesData.get(entry.getKey()).addAll(entry.getValue()));

}
publicstaticvoidmain(字符串[]args){
最终列表inputData=new ArrayList();
add(新的AbstractMap.SimpleEntry(“emp1”,Arrays.asList(“KY”,“NY”));
add(新的AbstractMap.SimpleEntry(“emp2”,Arrays.asList(“KY”,“NY”));
add(新的AbstractMap.SimpleEntry(“emp1”,Arrays.asList(“MN”,“FL”));
add(新的AbstractMap.SimpleEntry(“emp1”,Arrays.asList(“MN”,“FL”));
//如果您不关心重复项,请使用列表
最终地图可能重复数据=
inputData.stream()
.collect(Collectors.toMap(Map.Entry::getKey、,
条目->新建ArrayList());
inputData.stream()
.filter(entry->possibleWithDuplicatesData.containsKey(entry.getKey()))
.forEach(条目->
可能是重复数据.get(entry.getKey()).addAll(entry.getValue());
//如果要避免重复,请使用Set
最终地图节点重复数据=
inputData.stream()
.collect(Collectors.toMap(Map.Entry::getKey、,
条目->新建哈希集());
inputData.stream()
.filter(entry->noDuplicatesData.containsKey(entry.getKey()))
.forEach(条目->
noDuplicatesData.get(entry.getKey()).addAll(entry.getValue());
}
试试这个:

private static class Address {

    private String address;

    public Address(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
               "address='" + address + '\'' +
               '}';
    }
}

private static class Employee {

    private String name;
    private List<Address> addresses;

    public Employee(String name, List<Address> addresses) {
        this.name = name;
        this.addresses = addresses;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<Address> addresses) {
        this.addresses = addresses;
    }

    @Override
    public String toString() {
        return "Employee{" +
               "name='" + name + '\'' +
               ", addresses=" + addresses +
               '}';
    }
}

private static class MainDTO {

    private List<Employee> employees;

    public MainDTO(List<Employee> employees) {
        this.employees = employees;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "MainDTO{" +
               "employees=" + employees +
               '}';
    }
}

public static void main(String[] args) {
    List<Employee> employees = new ArrayList<>();
    employees.add(new Employee("emp1", Arrays.asList(new Address("KY"), new Address("NY"))));
    employees.add(new Employee("emp2", Arrays.asList(new Address("KY"), new Address("NY"))));
    employees.add(new Employee("emp1", Arrays.asList(new Address("MN"), new Address("FL"))));
    employees.add(new Employee("emp1", Arrays.asList(new Address("TN"), new Address("AZ"))));
    MainDTO dto = new MainDTO(employees);

    List<Employee> merged = dto.getEmployees().stream()
        .collect(Collectors.toMap(Employee::getName,
                                  e -> e,
                                  (l, r) ->
                                      new Employee(l.getName(),
                                                        Stream.concat(l.getAddresses().stream(), r.getAddresses().stream())
                                                              .collect(Collectors.toList())),
                                  LinkedHashMap::new))
        .values()
        .stream()
        .collect(Collectors.toList());

    System.out.println(merged);
}

如果Java 9是一个选项,您可以使用:

Map addressesByEmployeeName=empList
.stream()
.收集(分组)(
Employee::getName,flatMapping(
e->e.getAddresses().stream(),
toList());
但是我有一种奇怪的感觉,Java 9不是一个选项。

很好,因为它很好地利用了新的JDK 9
flatMapping
收集器。如果jdk9不是一个选项,那么可以在jdk8中执行类似的操作,尽管它需要更多的参与。它在流中执行平面映射操作,生成一个成对的员工姓名和地址流。我将使用
AbstractMap.SimpleEntry
,而不是创建一个特殊的pair类

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

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())));

创建地图条目对象并从中提取数据有些麻烦,但并不可怕。如果您愿意,可以将这里的一些习惯用法提取到实用方法中,以使事情变得更清晰。

如果您使用具有多重映射的库,例如

由于这种模式有些常见,我们可以向库中添加
RichIterable.toMultimap()
。那么这个例子可以归结为一行

MutableListMultimap<String, String> addressesByEmployeeName =
    empList.toMultimap(Employee::getName, Employee::getAddresses);
MutableListMultimap地址ByEmployeeName=
toMultimap(Employee::getName,Employee::getAddresses);

注意:我是Eclipse集合的提交者。

很好地使用了新的JDK 9特性+1.在JDK 8中实现这一点是可能的,尽管更复杂;看见
Map<String, List<String>> addressesByEmployeeName = empList
        .stream()
        .collect(groupingBy(
                Employee::getName, flatMapping(
                        e -> e.getAddresses().stream(),
                        toList())));
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())));
List<Employee> mergedEmps =
    mergedMap.entrySet().stream()
             .map(entry -> new Employee(entry.getKey(), entry.getValue()))
             .collect(toList());
ListIterable<Employee> empList = ...;
MutableSortedSetMultimap<String, String> addressesByEmployeeName =
    new TreeSortedSetMultimap<>();
empList.each(e -> e.getAddresses().each(a -> addressesByEmployeeName.put(e.getName(), a)));
ListAdapter.adapt(empList).each(
    e -> ListAdapter.adapt(e.getAddresses()).each(
        a -> addressesByEmployeeName.put(e.getName(), a)));
MutableListMultimap<String, String> addressesByEmployeeName =
    empList.toMultimap(Employee::getName, Employee::getAddresses);