Java 8 如何合并两个流并返回不同类型的列表?

Java 8 如何合并两个流并返回不同类型的列表?,java-8,java-stream,Java 8,Java Stream,我有两个流,我想把它们组合成不同的列表 i、 我有hashmap Map<String, List<String>> citiesByZip = new HashMap<>(); 人员名单 class Person { private String firstName; private String lastName; private int income; private int zipCode; People(

我有两个流,我想把它们组合成不同的列表 i、 我有hashmap

Map<String, List<String>> citiesByZip = new HashMap<>();
人员名单

  class Person {
    private String firstName;
    private String lastName;
    private int income;
    private int zipCode;



 People(String firstName, String lastName, int income, int zipCode) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.income = income;
        this.zipCode = zipCode;
    }

    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getIncome() {
        return income;
    }
    public int getZipCode() {
        return zipCode;
    }
}
 List<Person> persons= new ArrayList<>();
我想将列表中的每个人映射到县的hashmap,以找到哪个县的人居住

List <FinalObject> finalObjects= new  ArrayList<>();
finalObjects = Stream.concat(peopleStream.stream(), citiesByZip.entrySet().stream())
                .collect(Collectors.toMap(
                ))

我知道我可以在Java 7中使用传统循环完成这项工作,但我想知道我是否可以在Java 8中使用
流和lambda做同样的事情首先,您需要一个数据结构来高效查找特定的邮政编码,因为
Map
不适合这样做。你可以像这样转换它

Map<Integer,String> zipToCity = citiesByZip.entrySet().stream()
    .flatMap(e -> e.getValue().stream().map(Integer::valueOf)
                   .map(zip -> new AbstractMap.SimpleEntry<>(zip, e.getKey())))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
有了这个定义,您可以像这样使用zip查找进行转换

List<FinalObject> finalObjects = persons.stream()
    .map(p -> new FinalObject(p.getFirstName(), p.getLastName(),
                  p.getIncome(), zipToCity.getOrDefault(p.getZipCode(), "Unknown")))
    .collect(Collectors.toList());

List finalObjects=persons.stream()
.map(p->newfinalobject(p,zipToCity.getOrDefault(p.getZipCode(),“未知”))
.collect(Collectors.toList());

为我们提供(可编译)样本数据。我想您需要一个地图,其键是邮政编码,其值是与该邮政编码相关的城市。@Alexander完全正确,但我不知道如何引用其他流中的流给我们提供(可编译)样本数据。@kero在一个无关的注释中,您的
citiesByZip
地图实际上更像
zipsByCity
(邮政编码是按城市查找的,而不是按您的名字显示的其他方式)。另外,看看谷歌的番石榴图书馆。它非常适合您的用例(映射每个城市键的多个邮政编码值)。有几种方法可以“反转”多个地图,在给定的
zipsByCity
Junior Jane 20000 Alameda
Junior Jane 30000 Alameda
Joseph James 50000 Alameda
           .
           .
           etc
Map<Integer,String> zipToCity = citiesByZip.entrySet().stream()
    .flatMap(e -> e.getValue().stream().map(Integer::valueOf)
                   .map(zip -> new AbstractMap.SimpleEntry<>(zip, e.getKey())))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Map<Integer,String> zipToCity = citiesByZip.entrySet().stream()
    .collect(HashMap::new,
            (m,e) -> e.getValue().forEach(zip -> m.put(Integer.valueOf(zip), e.getKey())),
            Map::putAll);
class FinalObject {
    private String firstName, lastName, city;
    private int income;
    FinalObject(String firstName, String lastName, int income, String city) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.income = income;
        this.city = city;
    }

    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getIncome() {
        return income;
    }
    public String getCity() {
        return city;
    }
    @Override public String toString() {
        return firstName+" "+lastName+" "+income+" "+city;
    }
}
List<FinalObject> finalObjects = persons.stream()
    .map(p -> new FinalObject(p.getFirstName(), p.getLastName(),
                  p.getIncome(), zipToCity.getOrDefault(p.getZipCode(), "Unknown")))
    .collect(Collectors.toList());
class FinalObject {
    private Person p;
    String city;

    FinalObject(Person p, String city) {
        this.p = p;
        this.city = city;
    }

    public String getFirstName() {
        return p.getFirstName();
    }
    public String getLastName() {
        return p.getLastName();
    }
    public int getIncome() {
        return p.getIncome();
    }
    public String getCity() {
        return city;
    }
    @Override public String toString() {
        return getFirstName()+" "+getLastName()+" "+getIncome()+" "+city;
    }
}
List<FinalObject> finalObjects = persons.stream()
    .map(p -> new FinalObject(p, zipToCity.getOrDefault(p.getZipCode(), "Unknown")))
    .collect(Collectors.toList());