Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将多个映射与多个与值相同的键和列表结合起来?

如何将多个映射与多个与值相同的键和列表结合起来?
EN

Stack Overflow用户
提问于 2020-12-23 09:08:42
回答 2查看 1.2K关注 0票数 1

我是Java新手,我试图将多个以字符串作为键的映射合并,并将列表作为值来生成新的Map。

代码语言:javascript
运行
AI代码解释
复制
public class Student {
    private String name;
    private String country;

    //Setters and Getters
}

现在,我有了一个以国家为基础将学生列入名单的实用班。

代码语言:javascript
运行
AI代码解释
复制
public class MapAdder {
    static Map<String, List<Student>> studentMap =
            new LinkedHashMap<String, List<Student>>();

    public static void addToMap(String key, Student student) {
        studentMap.computeIfAbsent(key,
                k -> new LinkedList<Student>()).add(student);
    }

    public static Map<String, List<Student>> getStudentMap() {
        return studentMap;
    }

    public static void clearStudentMap() {
        studentMap.clear();
    }
}

主要方法

代码语言:javascript
运行
AI代码解释
复制
public static void main(String[] args) {
    Map<String, List<Student>> studentMap1;
    Map<String, List<Student>> studentMap2;
    Map<String, List<Student>> studentMap3;

    MapAdder.addToMap("India", new Student("Mounish", "India"));
    MapAdder.addToMap("USA", new Student("Zen", "USA"));
    MapAdder.addToMap("India", new Student("Ram", "India"));
    MapAdder.addToMap("USA", new Student("Ronon", "USA"));
    MapAdder.addToMap("UK", new Student("Tony", "UK"));

    studentMap1 = MapAdder.getStudentMap();
    MapAdder.clearStudentMap();

    MapAdder.addToMap("India", new Student("Rivar", "India"));
    MapAdder.addToMap("UK", new Student("Loki", "UK"));
    MapAdder.addToMap("UK", new Student("Imran", "UK"));
    MapAdder.addToMap("USA", new Student("ryan", "USA"));

    studentMap2 = MapAdder.getStudentMap();
    MapAdder.clearStudentMap();

    Map<String, List<Student>> map3 = Stream.of(studentMap1, studentMap2)
            .flatMap(map -> map.entrySet().stream())
            .collect(Collectors.toMap(
                    Entry::getKey,
                    Entry::getValue
            ));
}

但是当我试图合并这两个地图时,我得到的是空地图。实际上,我需要一个包含三个键(印度、英国、美国)的地图,它们的值是从多个要合并的w.r.t键中列出的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-23 09:19:39

首先,从代码中删除以下调用:

代码语言:javascript
运行
AI代码解释
复制
MapAdder.clearStudentMap();

您正在清除studentMap1studentMap2

当你这样做时:

代码语言:javascript
运行
AI代码解释
复制
studentMap1 = MapAdder.getStudentMap();

您将获得存储学生Map的内存引用。当您在地图上调用clear方法时

代码语言:javascript
运行
AI代码解释
复制
studentMap.clear();

您将清除存储在同一内存引用上的所有Map条目。换句话说,以下声明

代码语言:javascript
运行
AI代码解释
复制
studentMap1 = MapAdder.getStudentMap();

不创建学生Map的副本,而是将对该地图的内存引用保存在变量studentMap1上。

您的Stream方法几乎是正确的,将其更改为:

代码语言:javascript
运行
AI代码解释
复制
Map<String, List<Student>> map3 = Stream.of(studentMap1, studentMap2)
        .flatMap(map -> map.entrySet().stream())
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                e -> new ArrayList<>(e.getValue()),
                (left, right) -> { left.addAll(right); return left; }
        ));

您还需要添加用于处理重复键(即mergeFunction方法的Collectors.toMap参数)的策略。在重复键的情况下,我们将Map值添加到左键的列表中。

顺便提一下,这些帮助方法中的一些--它们混淆了代码,并通过传递addToMap本身作为参数,使Map方法更加通用,这样您就可以在不同的映射器中重用该方法,即:

代码语言:javascript
运行
AI代码解释
复制
public class MapAdder {
    public static void addToMap(Map<String, List<Student>> studentMap,
                                String key, Student student) {
        studentMap.computeIfAbsent(key,
                k -> new LinkedList<Student>()).add(student);
    }

    public static void main(String[] args) {
        Map<String, List<Student>> studentMap1 = new LinkedHashMap<>();
        Map<String, List<Student>> studentMap2 = new LinkedHashMap<>();
        Map<String, List<Student>> studentMap3;

        MapAdder.addToMap(studentMap1, "India", new Student("Mounish", "India"));
        MapAdder.addToMap(studentMap1, "USA", new Student("Zen", "USA"));
        MapAdder.addToMap(studentMap1, "India", new Student("Ram", "India"));
        MapAdder.addToMap(studentMap1, "USA", new Student("Ronon", "USA"));
        MapAdder.addToMap(studentMap1, "UK", new Student("Tony", "UK"));

        MapAdder.addToMap(studentMap2, "India", new Student("Rivar", "India"));
        MapAdder.addToMap(studentMap2, "UK", new Student("Loki", "UK"));
        MapAdder.addToMap(studentMap2, "UK", new Student("Imran", "UK"));
        MapAdder.addToMap(studentMap2, "USA", new Student("ryan", "USA"));

        Map<String, List<Student>> map3 = Stream.of(studentMap1, studentMap2)
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        e -> new ArrayList<>(e.getValue()),
                        (left, right) -> { left.addAll(right); return left; }
                ));
    }
}
票数 2
EN

Stack Overflow用户

发布于 2020-12-23 19:04:04

主要问题是您一直在清除共享列表。需要建立独立的名单。

但是,有一种添加值的方法比使用MapAdder类容易得多。记住,country也是学生班级的一部分。因此,只要提取它,并创建地图使用流。

现在创建studentMap1

代码语言:javascript
运行
AI代码解释
复制
List<Student> list1 = List.of(
new Student("Mounish", "India"),
new Student("Zen", "USA"),
new Student("Ram", "India"),
new Student("Ronon", "USA"),
new Student("Tony", "UK"));
Map<String, List<Student>> studentMap1 = 
     list1.stream().collect(Collectors.groupingBy(Student::getCountry));

studentMap1.entrySet().forEach(System.out::println);

版画

代码语言:javascript
运行
AI代码解释
复制
USA=[{Zen,  USA}, {Ronon,  USA}]
UK=[{Tony,  UK}]
India=[{Mounish,  India}, {Ram,  India}]

现在创建studentMap2

代码语言:javascript
运行
AI代码解释
复制
List<Student> list2 = List.of(
new Student("Rivar", "India"),
new Student("Loki", "UK"),
new Student("Imran", "UK"),
new Student("ryan", "USA"));
Map<String, List<Student>> studentMap2 = 
   list2.stream().collect(Collectors.groupingBy(Student::getCountry));

studentMap2.entrySet().forEach(System.out::println);

打印

代码语言:javascript
运行
AI代码解释
复制
USA=[{ryan,  USA}]
UK=[{Loki,  UK}, {Imran,  UK}]
India=[{Rivar,  India}]

现在您已经拥有了映射,您可以以相同的方式创建组合映射。只需使用每个地图的值,然后流他们得到学生的实例。

代码语言:javascript
运行
AI代码解释
复制
Map<String, List<Student>> map3 = Stream.of(studentMap1,studentMap2)
        .map(Map::values)               // values which is a collection of lists
        .flatMap(Collection::stream)    // flat map the two collections
        .flatMap(Collection::stream)    // flat map the lists to just
                                        // a stream of students
        .collect(Collectors.groupingBy(Student::getCountry));

map3.entrySet().forEach(System.out::println);

打印

代码语言:javascript
运行
AI代码解释
复制
USA=[{Zen,  USA}, {Ronon,  USA}, {ryan,  USA}]
UK=[{Tony,  UK}, {Loki,  UK}, {Imran,  UK}]
India=[{Mounish,  India}, {Ram,  India}, {Rivar,  India}]

幸运的是,Map键作为学生类的一部分包含在其中。但让我们假设密钥独立于类之外。然后,您可以使用您的mapAdder构建原始地图。最后的映射可以使用下面的merge函数创建,用于合并重复的键。

代码语言:javascript
运行
AI代码解释
复制
Map<String, List<Student>> map4 =
   Stream.of(studentMap1, studentMap2)
        .flatMap(m -> m.entrySet().stream())
        .collect(Collectors.toMap(Entry::getKey,
            e -> new ArrayList<>(e.getValue),
           (lst1, lst2) -> {lst1.addAll(lst2); return lst1;}));

带有getter、setter和toString的学生类

代码语言:javascript
运行
AI代码解释
复制
class Student {
    private String name;
    private String country;
    
    public Student(String name, String country) {
        this.name = name;
        this.country = country;
    }
    
    public String getName() {
        return name;
    }
    
    public String getCountry() {
        return country;
    }
    
    @Override
    public String toString() {
        return String.format("{%s,  %s}", name, country);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65428163

复制
相关文章
C# 存储相同键多个值的Dictionary
C盘下面有个根文件夹SaveFile,SaveFIle下面有两个子文件夹分别为,2018、2019,
用户7053485
2020/03/12
4.6K0
Python学习记录06-字典中的键映射多个值
如果想一个key映射多个value, 我们就需要让value也是一个容器,可以是列表,也可以集合。看具体的使用场景。列表的特性是可以保持顺序,集合的特性是可以去重。 可以用以下的方式来创建一个映射多个value 的字典
huolong
2023/09/07
7710
python3 列表内多个字典 相同
需求 计算 列表内 名字一样的 value 值 name = [ {'name': 'he', 'value': 100, 'ps': 'test1'}, {'name': 'quan', 'value': 150, 'ps': 'test2'}, {'name': 'he', 'value': 100, 'ps': 'test3'}, {'name': 'quan', 'value': 200, 'ps': 'test4'} ] 代码 pip install pan
py3study
2020/01/03
6400
【说站】Python切片获取列表多个值
1、单个值可以通过下标获得,多个值可以通过切片获得,并返回一个新列表。将切片输入方括号,用冒号分割。
很酷的站长
2022/11/24
1.2K0
【说站】Python切片获取列表多个值
多个FeignClient使用相同的name
FeignClient标签默认使用name属性作为bean name,name属性同时为服务名。 如果指定了contextId属性,则使用contextId作为bean name。 如此可为一个服务创建多个FeignClient: @FeignClient(name = "my-service-id", contextId = "my-service-id-api1") public interface Api1FeignClient { } @FeignClient(name = "my-service
路过君
2020/12/17
3.6K0
Excel公式练习58: 获取与查找值相对应的多个值
导语:本文所讲的案例在第一季公式练习中有相似的例子,这里再巩固一下。只要知道要在公式中使用的函数,没有Excel解决不了的问题!
fanjy
2020/04/22
2.9K0
python find()找多个相同子
#!coding:utf-8 cont="find()方法判断字符串str,如果起始索引beg和结束end索引能找到在字符串或字符串的一个子串中。" S_a=cont.find('字符串') S_b=cont.find('字符串',S_a) print(S_a) #18 print(S_b) #18 上面代码直接用返回的S_a的值寻找的是相同位置 S_a=cont.find('字符串') S=S_a+1 S_b=cont.find('字符串',S) print(S_a)
py3study
2020/01/08
2.4K0
Python元组与列表的相同点与区别
列表和元组都属于有序序列,支持使用双向索引访问其中的元素、使用内置函数len()统计元素个数、使用运算符in测试是否包含某个元素、使用count()方法统计指定元素的出现次数和index()方法获取指定元素的索引。虽然有着一定的相似之处,但列表和元组在本质上和内部实现上都有着很大的不同。 元组属于不可变(immutable)序列,一旦创建,不允许修改元组中元素的值,也无法为元组增加或删除元素。因此,元组没有提供append()、extend()和insert()等方法,无法向元组中添加元素;同样,元组也没有
Python小屋屋主
2018/04/16
1.7K0
多个网卡使用相同IP的网卡绑定
多个网卡想单独使用的话可以使用不同的IP绑定,但是这样比较麻烦,也可以使用相同的IP,这样一个设备虽然有多个网卡,但只有一个IP,可以将需要的程序socket绑定到固定的网卡。这样虽然是相同的IP,但是可以独立使用了。
用户9736681
2023/02/20
4K0
多个网卡使用相同IP的网卡绑定
jquery validate 如何校验多个相同name
本文来源 : http://www.cnblogs.com/danywdd/p/5667903.html
翟凤玺
2020/10/29
1.1K0
Excel公式练习59: 获取与满足多个查找条件的所有值
导语:本文所讲的案例在第一季公式练习中有相似的例子,这里再巩固一下。只要知道要在公式中使用的函数,没有Excel解决不了的问题!
fanjy
2020/04/28
3K0
验证多个class相同的input框不为空
要求,页面有多个class相同的input输入框,在提交数据的时候,进行验证,验证input框不能为空,如果哪个为空,则弹出提示:
王小婷
2020/05/26
1.9K0
验证多个class相同的input框不为空
函数的多个返回值
def func1(): # return 值1,值2 --- return有一个作用是打断程序的运行 return 1 + 1 , 2 + 2, 3+4 num1,num2,num3 = func1() print(func1()) print(num1) print(num2) print(num3)
汪凡
2018/05/29
6K0
ASP获取多个CheckBox的值
<form id="form" name="form" method="post" action="/temp/test9.asp">    <input name="yi" type="checkbox" id="yi" value="111" />    <input name="yi" type="checkbox" id="yi" value="222" />    <input name="yi" type="checkbox" id="yi" value="333" />    <input type="submit" name="Submit" value="提交" /> </form>
Tony老师
2020/03/05
5.6K0
python输出多个变量的值。
有点类似于C语言 print("%s,%d,%d"%(name ,age ,school))
py3study
2020/01/10
5.3K0
Jquery如何删除table里面checkbox选中的多个行与多个列
(adsbygoogle = window.adsbygoogle || []).push({});
tianyawhl
2019/04/04
4.5K0
java:函数--返回多个值
1、【使用集合类】使用map返回值;这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过源代码来查看。
用户7886150
2020/12/14
2.8K0
解决validate无法验证多个相同name的input
用户9131103
2023/07/17
3620
map合并,相同键对应的值相加
最近在做统计钱的计算时遇到的一个需求,需要将一个大类别下的每一种钱进行特定的运算然后获得六年的钱,最后将这些钱按照年份进行汇总,获得总得大类型的六年的钱,在这个过程中采用了这种方法,每次算得钱放在map中,然后将map进行合并,写篇随笔mark下。
河岸飞流
2019/08/09
4.1K0
Golang flag 获取多个值
但是在某些情况下,我们要对一个key指定多个值。 并获取多个值得数组。 这时我们需要定义一个Type Value接口类型
用户1416054
2018/08/02
4.6K0

相似问题

映射与复杂键的多个索引

22

从多个映射和键列表到映射中的键和相应值的列表

40

yml -多个键映射到相同的值

151

Groovy映射中相同键的多个值

118

具有多个键映射到相同值的字典

568
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档