Java 如何转换列表<;SomeType>;映射保留所有重复的键和值

Java 如何转换列表<;SomeType>;映射保留所有重复的键和值,java,data-structures,collections,java-8,Java,Data Structures,Collections,Java 8,我的清单如下: List<Address> address; 我想把它转换成下面这样的东西 Map <String,String> convertedMap=list.stream().collect (Collectors.toMap(Address:getCity+Address:getCountry ,Address:getState)); 如注释中所述,映射不存储重复的键,因此您必须使用Map而不是Map 总之,您只需使用Collectors.toMap方法

我的清单如下:

List<Address> address;
我想把它转换成下面这样的东西

Map <String,String> convertedMap=list.stream().collect
(Collectors.toMap(Address:getCity+Address:getCountry ,Address:getState)); 

如注释中所述,映射不存储重复的键,因此您必须使用
Map
而不是
Map

总之,您只需使用
Collectors.toMap
方法和
mergeFunction
参数即可处理重复的键。每次出现相同的键时都会调用此操作。在本例中,我们只需将两个列表合并为一个。看看下面的代码(用JDK11编译),我相信它完全满足您的需要,并打印出预期的结果(当然使用
List

import java.util.*;
导入java.util.stream.collector;
公共类列表包含DuplicatedKeysSample{
公共静态void main(字符串[]args){
列表地址=List.of(
新地址(“城市1”、“国家1”、“州1”),
新地址(“城市1”、“国家1”、“州2”),
新地址(“城市1”、“国家1”、“州1”),
新地址(“城市3”、“国家3”、“州3”)
);
映射结果=addresses.stream()
.收集(
汤姆(
地址->地址.getCity()+地址.getCountry(),
address->Collections.singletonList(address.getState()),
ListToMapWithDuplicatedKeysSample::MergeEntries with DuplicatedKeys
)
);
系统输出打印项次(结果);
}
私有静态列表mergeEntriesWithDuplicatedKeys(列出现有结果,列出新结果){
List mergedResults=new ArrayList();
mergedResults.addAll(现有结果);
mergedResults.addAll(新结果);
返回合并结果;
}
私有静态类地址{
私人城市;
私人国家;
私有最终字符串状态;
公共广播(字符串城市、字符串国家、字符串州){
this.city=城市;
这个国家=国家;
this.state=状态;
}
字符串getState(){
返回状态;
}
字符串getCountry(){
返回国;
}
字符串getCity(){
回归城市;
}
}
}

如注释中所述,地图不存储重复的密钥,因此您必须使用
Map
而不是
Map

总之,您只需使用
Collectors.toMap
方法和
mergeFunction
参数即可处理重复的键。每次出现相同的键时都会调用此操作。在本例中,我们只需将两个列表合并为一个。看看下面的代码(用JDK11编译),我相信它完全满足您的需要,并打印出预期的结果(当然使用
List

import java.util.*;
导入java.util.stream.collector;
公共类列表包含DuplicatedKeysSample{
公共静态void main(字符串[]args){
列表地址=List.of(
新地址(“城市1”、“国家1”、“州1”),
新地址(“城市1”、“国家1”、“州2”),
新地址(“城市1”、“国家1”、“州1”),
新地址(“城市3”、“国家3”、“州3”)
);
映射结果=addresses.stream()
.收集(
汤姆(
地址->地址.getCity()+地址.getCountry(),
address->Collections.singletonList(address.getState()),
ListToMapWithDuplicatedKeysSample::MergeEntries with DuplicatedKeys
)
);
系统输出打印项次(结果);
}
私有静态列表mergeEntriesWithDuplicatedKeys(列出现有结果,列出新结果){
List mergedResults=new ArrayList();
mergedResults.addAll(现有结果);
mergedResults.addAll(新结果);
返回合并结果;
}
私有静态类地址{
私人城市;
私人国家;
私有最终字符串状态;
公共广播(字符串城市、字符串国家、字符串州){
this.city=城市;
这个国家=国家;
this.state=状态;
}
字符串getState(){
返回状态;
}
字符串getCountry(){
返回国;
}
字符串getCity(){
回归城市;
}
}
}

这种类型的东西是许多编码挑战的常见要求,下面是一种快速完成所需内容的方法如果您有时间限制,我选择使用集合而不是列表,查找时间为O(1)而不是O(N):


注:我认为你应该使用一个类似于<代码>、<代码>的分隔符,而不是一个空间,这样处理多个词的城市会更容易,例如纽约、旧金山等。

< P>这种类型的东西是很多编码挑战的共同要求。如果您有时间限制,我选择使用集合而不是列表,查找时间为O(1)而不是O(N),这是一种快速实现所需功能的方法:


注:我认为你应该使用一个类似于<代码>、<代码>的分隔符,而不是一个空间,这样处理多个词的城市就更容易了。例如纽约、旧金山等。

< p>你不能使用CalcReultsTAMAP,因为它需要唯一的密钥。您需要的是groupingBy,它返回每个键的收集值:

class Location {
    public final String city;
    public final String country;

    Location(Address address) {
        this.city = address.getCity();
        this.country = address.getCountry();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Location) {
            Location other = (Location) obj;
            return Objects.equals(this.city, other.city) &&
                   Objects.equals(this.country, other.country);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, country);
    }
}

Map<Location, Set<String>> statesByLocation = addresses.stream().collect(
    Collectors.groupingBy(Location::new,
        Collectors.mapping(Address::getState, Collectors.toSet())));

您不能使用Collectors.toMap,因为它需要唯一的密钥。您需要的是groupingBy,它返回每个键的收集值:

class Location {
    public final String city;
    public final String country;

    Location(Address address) {
        this.city = address.getCity();
        this.country = address.getCountry();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Location) {
            Location other = (Location) obj;
            return Objects.equals(this.city, other.city) &&
                   Objects.equals(this.country, other.country);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, country);
    }
}

Map<Location, Set<String>> statesByLocation = addresses.stream().collect(
    Collectors.groupingBy(Location::new,
        Collectors.mapping(Address::getState, Collectors.toSet())));

使用带有以下方法签名的toMap

   toMap(Function k, Function v,BinaryOperator m)
二进制运算符通知
{PortlandUSA=[ME, OR], BostonUSA=[MA]}
class Location {
    public final String city;
    public final String country;

    Location(Address address) {
        this.city = address.getCity();
        this.country = address.getCountry();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Location) {
            Location other = (Location) obj;
            return Objects.equals(this.city, other.city) &&
                   Objects.equals(this.country, other.country);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, country);
    }
}

Map<Location, Set<String>> statesByLocation = addresses.stream().collect(
    Collectors.groupingBy(Location::new,
        Collectors.mapping(Address::getState, Collectors.toSet())));
Map<Location, Set<String>> statesByLocation = new HashMap<>();
for (Address address : addresses) {
    statesByLocation.computeIfAbsent(new Location(address),
        k -> new HashSet<String>()).add(address.getState());
}
   toMap(Function k, Function v,BinaryOperator m)
  Map<String, String> map = list.stream().
            collect(Collectors.toMap((address -> {
                String y = address.getCity() + address.getCountry();
                return y + s;
            }), Address::getState, (s1, s2) -> s1 + "," + s2));
     country3City3  state3
     country1City1  state1,state2,state1

      Process finished with exit code 0