Java 8 将List转换为Map

2018-03-27 16:37:57

几个Java 8示例来向您展示如何将一个List对象转换为一个Map,以及如何处理重复的键

Hosting.java

package com.mkyong.java8public class Hosting {
    private int Id;
    private String name;
    private long websites;
    public Hosting(int id, String name, long websites) {
        Id = id;
        this.name = name;
        this.websites = websites;
    }
    //getters, setters and toString()}

List到Map - Collectors.toMap()


创建Hosting对象的List,Collectors.toMap并将其转换为Map。

TestListMap.java

package com.mkyong.java8import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class TestListMap {
    public static void main(String[] args) {
        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
        // key = id, value - websites
        Map<Integer, String> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getId, Hosting::getName));
        System.out.println("Result 1 : " + result1);
        // key = name, value - websites
        Map<String, Long> result2 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites));
        System.out.println("Result 2 : " + result2);
        // Same with result1, just different syntax
        // key = id, value = name
        Map<Integer, String> result3 = list.stream().collect(
                Collectors.toMap(x -> x.getId(), x -> x.getName()));
        System.out.println("Result 3 : " + result3);
    }}

Output

Result 1 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}Result 2 : {liquidweb.com=80000, mkyong.com=1, digitalocean.com=120000, aws.amazon.com=200000, linode.com=90000}Result 3 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}

2.列出Map - 重复键

2.1运行下面的代码,重复的关键错误将被抛出!

TestDuplicatedKey.java

package com.mkyong.java8;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class TestDuplicatedKey {
    public static void main(String[] args) {
        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
        list.add(new Hosting(6, "linode.com", 100000)); // new line
        // key = name, value - websites , but the key 'linode' is duplicated!?
        Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites));
        System.out.println("Result 1 : " + result1);
    }}

输出 - 下面的错误信息有点误导,应该显示“linode”而不是键的值。

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 90000
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1245)
	//...

2.2要解决上述重复的关键问题,请传入第三个mergeFunction参数,如下所示:

Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites,
                        (oldValue, newValue) -> oldValue                )
        );

Output

Result 1 : {..., aws.amazon.com=200000, linode.com=90000}

3.3尝试newValue

Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites,
                        (oldValue, newValue) -> newvalue                )
        );

Output

Result 1 : {..., aws.amazon.com=200000, linode.com=100000}

3.列出Map- 排序Collect

TestSortCollect.java

package com.mkyong.java8;import java.util.*;import java.util.stream.Collectors;public class TestSortCollect {
    public static void main(String[] args) {
        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
        list.add(new Hosting(6, "linode.com", 100000));
        //example 1
        Map result1 = list.stream()
                .sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
                .collect(
                        Collectors.toMap(
                                Hosting::getName, Hosting::getWebsites, // key = name, value = websites
                                (oldValue, newValue) -> oldValue,       // if same key, take the old key
                                LinkedHashMap::new                      // returns a LinkedHashMap, keep order
                        ));
        System.out.println("Result 1 : " + result1);
    }}

Output

Result 1 : {aws.amazon.com=200000, digitalocean.com=120000, linode.com=100000, liquidweb.com=8000
  • 2020-12-06 19:05:13

    visual studio 配置 intellij idea快捷键

    我原本从intellij idea转换到visual studio是因为webstorm没办法远程开发,而visual studio有remote wsl,和remote ssh,看着挺不错的样子。

  • 2020-12-06 20:38:30

    intellij idea远程开发remote

    开发时一般的平台都是windows,但windows对开发极其不友好,一般都会在本地开启虚拟机,安装上linux环境进行项目的部署测试。下面介绍一种windows主机与linux虚拟机代码同步的方法。这个工具适用于jerbrains公司旗下的很多产品,比如idea、webstrom、phpstrom等。但是要注意你安装的IDE必须是专业版的,社区版的IDE是没有这个代码同步功能的哦!

  • 2020-12-07 05:46:56

    npm设置和取消代理的方法

    有时候是设置了全局代理对npm并不生效,不如直接给npm设置代理,至少在mac电脑我是有这种感觉的。

  • 2020-12-07 15:04:03

    node开发邮件系统总结

    因为multipart这种形式比较复杂,因此要利用boundary分割符,将邮件体分割成不同段来进行解析,boundary分为父段和子段,父段一般出现0次或1次,出现在末尾,每个子段中也有content-type和boundary,需要在进行解析,如果遇到i,iii里面的情况可直接解析,如果遇到ii中的情况,再按ii中的步骤进行解析

  • 2020-12-07 15:17:45

    email-templates + mjml 发送邮件

    mjml 是一个很不错的响应式邮件html 内容标签库,email-templates 是一个灵活强大的邮件发送框架,两者集成起来我们 可以设计灵活强大的邮件发送系统,以下是一个简单的集成使用,实际使用还有好多地方需要完善

  • 2020-12-07 15:19:00

    响应式邮件的编写插件介绍mjml

    以前做项目碰到发邮件的需求,邮件模板的编辑就是一件头疼的事。因为虽说邮件是支持 HTML 的,但是确是 HTML 子集程度的支持,所以存在必须通过 <table> 排版的恶心之处,还有很多兼容性的坑。本质上是各家邮件商的标准有差异吧。

  • 2020-12-07 16:14:22

    nodejs队列实现amqplib,rabbitmq

    其中StartConsumer 会在项目启动时启动,在整个生命周期中一直保持监听状态,在程序结束时mq的链接关闭。需要注意的是 noAck 这个参数,当为false是表示消息出队后不会自动删除,如果设置成true,则无论消息处理成功与否此消息会被删除。注意到在消息不成功是,调用了ch.nack(msg)),此方法是将消息重新入队。

  • 2020-12-07 16:15:46

    RabbitMQ详解

    当前市面上mq的产品很多,比如RabbitMQ、Kafka、ActiveMQ、ZeroMQ和阿里巴巴捐献给Apache的RocketMQ。甚至连redis这种NoSQL都支持MQ的功能。 ActiveMQ ActiveMQ是apache出品,最流行的,能力强劲的开源消息总线,并且它一个完全支持JMS规范的消息中间件。其丰富的API、多种集群构建模式使得它成为业界老牌消息中间件,在中小型企业中应用广泛。