Java中List转Map List实现的几种姿势

今天介绍一个实用的小知识点,如何将List转为Map<Object, List<Object>>

1. 基本写法

最开始介绍的当然是最常见、最直观的写法,当然也是任何限制的写法

// 比如将下面的列表,按照字符串长度进行分组
List<String> list = new ArrayList<>();
list.add("hello");
list.add("word");
list.add("come");
list.add("on");
Map<Integer, List<String>> ans = new HashMap<>();

for(String str: list) {
    List<String> sub = ans.get(str.length());
    if(sub == null) {
        sub = new ArrayList<>();
        ans.put(str.length(), sub);
    }
    sub.add(str);
}
System.out.println(ans);

对于jdk8+,上面for循环中的内容可以利用Map.computeIfAbsent来替换,具体写法如下

for (String str : list) {
    ans.computeIfAbsent(str.length(), k -> new ArrayList<>()).add(str);
}

当然既然已经是jdk1.8了,借助Stream的流处理,可以将上面的更一步进行简化,如下

Map<Integer, List<String>> ans = list.stream().collect(Collectors.groupingBy(String::length));

2. 通用方法

上面是针对特定的列表,针对业务进行开发转换,那么我们接下来尝试构建一个通用的工具类

这里我们主要借助的知识点就是泛型,一个重要的点就是如何获取Map中的key
对于jdk < 1.8的写法,通过接口来定义实现key的获取姿势

public static <K, V> Map<K, List<V>> toMapList(List<V> list, KeyFunc<V, K> keyFunc) {
    Map<K, List<V>> result = new HashMap<>();
    for (V item: list) {
        K key = keyFunc.getKey(item);
        if (!result.containsKey(key)) {
            result.put(key, new ArrayList<>());
        }
        result.get(key).add(item);
    }
    return result;
}

public static interface KeyFunc<T, K> {
    K getKey(T t);
}

使用demo如下

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("hello");
    list.add("word");
    list.add("come");
    list.add("on");
    Map<Integer, List<String>> res = toMapList(list, new KeyFunc<String, Integer>() {
        @Override
        public Integer getKey(String s) {
            return s.length();
        }
    });
    System.out.println(res);
}

接下来再看一下jdk1.8之后的写法,结合stream + 函数方法来实现

public static <K, V> Map<K, List<V>> toMapList(List<V> list, Function<V, K> func) {
    return list.stream().collect(Collectors.groupingBy(func));
}

其对应的使用方式则如下

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("hello");
    list.add("word");
    list.add("come");
    list.add("on");
    Map<Integer, List<String>> res = toMapList(list, (Function<String, Integer>) String::length);
    System.out.println(res);
}

3. 工具类

上一节介绍了基于泛型 + jdk8 Stream + 函数方法来实现通用转换工具类的实现姿势,接下来我们小结一下,输出一个适用于1.8之后的工具类

/**
 * List<V>转换为Map<K, List<V>> 特点在于Map中的value,是个列表,且列表中的元素就是从原列表中的元素
 *
 * @param list
 * @param func 基于list#item生成Map.key的函数方法
 * @param <K>
 * @param <V>
 * @return
 */
public static <K, V> Map<K, List<V>> toMapList(List<V> list, Function<V, K> func) {
    return list.stream().collect(Collectors.groupingBy(func));
}

/**
 * List<I>转换为Map<K, List<V>> 特点在于Map中的value是个列表,且列表中的元素是由list.item转换而来
 *
 * @param list
 * @param keyFunc 基于list#item生成的Map.key的函数方法
 * @param valFunc 基于list#item转换Map.value列表中元素的函数方法
 * @param <K>
 * @param <I>
 * @param <V>
 * @return
 */
public static <K, I, V> Map<K, List<V>> toMapList(List<I> list, Function<I, K> keyFunc, Function<I, V> valFunc) {
    return list.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valFunc, Collectors.toList())));
}

4.guava HashMultimap扩展知识点

最后再介绍一个扩展知识点,Gauva工具包中提供了一个HashMultimap的工具类,他的使用姿势和我们平常的Map并无差别,但是需要在注意的是,它的value是个集合

List<String> list = new ArrayList<>();
list.add("hello");
list.add("word");
list.add("come");
list.add("on");
list.add("on");
HashMultimap<Integer, String> map = HashMultimap.create();
for (String item: strList) {
    map.put(item.length(), item);
}
System.out.println(map);

实际输出如下,验证了value实际上是个集合(on只有一个,如果是我们上面的工具类,会输出两个)

{2=[on], 4=[word, come], 5=[hello]}

到此这篇关于Java中List转Map List实现的几种姿势的文章就介绍到这了,更多相关Java中List转Map List内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java中数组list map三者之间的互转介绍

    三者之间转换关系,一张图清晰呈现.  上代码: 其中的maputils是apache的collection包. 复制代码 代码如下: package util; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.MapUtil

  • java中实现list或set转map的方法

    java中实现list或set转map的方法 在开发中我们有时需要将list或set转换为map(比如对象属性中的唯一键作为map的key,对象作为map的value),一般的想法就是new一个map,然后把list或set中的值一个个push到map中. 类似下面的代码: List<String> stringList = Lists.newArrayList("t1", "t2", "t3"); Map<String, St

  • 详解Java8新特性Stream之list转map及问题解决

    List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap 具体用法实例如下: //声明一个List集合 List<Person> list = new ArrayList(); list.add(new Person("1001", "小A")); list.add(new Person("1002", "小B")); list.add(new Person

  • Java8中List转Map(Collectors.toMap) 的技巧分享

    前言 在实际项目中我们经常会用到 List 转 Map 操作,在过去我们可能使用的是 for 循环遍历的方式.举个例子: 先定义类: // 简单对象 @Accessors(chain = true) // 链式方法 @lombok.Data class User { private String id; private String name; } 然后有这样一个 List: List<User> userList = Lists.newArrayList( new User().setId(

  • Java lambda list转换map时,把多个参数拼接作为key操作

    我就废话不多说了,大家还是直接看代码吧~ Map<String, Parts> partsMap = synList.stream().collect(Collectors.toMap(k -> k.getOe()+k.getOeId()+k.getPartGroupId()+k.getStdPartId()+k.getBrandCode(), part -> part)); 补充知识:Java8 Collectors.toMap的两个大坑 Collectors.toMap()方法

  • 在Java 8中将List转换为Map对象方法

    假设有一个员工对象: <b>public</b> <b>class</b> Employee { <font><i>// member variables</i></font><font> <b>private</b> <b>int</b> empId; <b>private</b> String empName; <b&

  • Java Lambda List转Map代码实例

    在有些开发场景,需要对 List 对象列表进行过滤处理,并将有用的数据存放到Map中. 例如:告警对象,包含告警uuid(alarmUuid) 和 设备uuid(objUuid),需要对 objUuid = -1的告警进行过滤,并将过滤后告警数据的alarmUuid和 objUuid以键值对的形式保存到Map中. 1.告警对象定义如下: /** * Created by Miracle Luna on 2020/3/16 */ public class AlarmInfoResponse { p

  • Java8 将一个List<T>转为Map<String,T>的操作

    将 List 转为 Map<String, T> public class AnswerApp { public static void main(String[] args) throws Exception { List<String> names = Lists.newArrayList("Answer", "AnswerAIL", "AI"); Map<String, Integer> map = na

  • Java中List转Map List实现的几种姿势

    今天介绍一个实用的小知识点,如何将List转为Map<Object, List<Object>> 1. 基本写法 最开始介绍的当然是最常见.最直观的写法,当然也是任何限制的写法 // 比如将下面的列表,按照字符串长度进行分组 List<String> list = new ArrayList<>(); list.add("hello"); list.add("word"); list.add("come&qu

  • 详解Java中list,set,map的遍历与增强for循环

    详解Java中list,set,map的遍历与增强for循环 Java集合类可分为三大块,分别是从Collection接口延伸出的List.Set和以键值对形式作存储的Map类型集合. 关于增强for循环,需要注意的是,使用增强for循环无法访问数组下标值,对于集合的遍历其内部采用的也是Iterator的相关方法.如果只做简单遍历读取,增强for循环确实减轻不少的代码量. 集合概念: 1.作用:用于存放对象 2.相当于一个容器,里面包含着一组对象,其中的每个对象作为集合的一个元素出现 3.jav

  • java中 Set与Map排序输出到Writer详解及实例

     java中 Set与Map排序输出到Writer详解及实例 一般来说java.util.Set,java.util.Map输出的内容的顺序并不是按key的顺序排列的,但是java.util.TreeMap,java.util.TreeSet的实现却可以让Map/Set中元素内容以key的顺序排序,所以利用这个特性,可以将Map/Set转为TreeMap,TreeSet然后实现排序输出. 以下是实现的代码片段: /** * 对{@link Map}中元素以key排序后,每行以{key}={val

  • Java中对list map根据map某个key值进行排序的方法

    实例如下所示: package test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; public class java_ListMapSort { public static void main(String[] args)

  • 浅析java中Pair和Map的区别

    在这篇文章中,我们讨论了一个非常有用的编程概念,配对(Pair).配对提供了一种方便方式来处理简单的键值关联,当我们想从方法返回两个值时特别有用. 在核心Java库中可以使用配对(Pair)的实现.除此之外,某些第三方库,比如Apache Commons和Vavr,已经在各自的api中公开了这个功能. 核心java配对实现 Pair类 Pair类在javafx.util 包中,类构造函数有两个参数,键及对应值: Pair<Integer, String> pair = new Pair<

  • Java中实现文件上传下载的三种解决方案(推荐)

    java文件上传与文件下载是程序开发中比较常见的功能,下面通过本文给大家介绍Java中实现文件上传下载的三种解决方案,具体详情如下所示: 第一点:Java代码实现文件上传 FormFile file=manform.getFile(); String newfileName = null; String newpathname=null; String fileAddre="/numUp"; try { InputStream stream = file.getInputStream(

  • Java中for、while、do while三种循环语句的区别介绍

    本文通过实例讲解给大家介绍Java中for.while.do while三种循环语句的区别,具体详情如下所示: 第一种:for循环 循环结构for语句的格式: for(初始化表达式;条件表达式;循环后的操作表达式) { 循环体; } eg: class Dome_For2{ public static void main(String[] args) { //System.out.println("Hello World!"); //求1-10的偶数的和 int sum = 0; fo

  • java中ThreadLocal取不到值的两种原因

    1.两种原因 第一种,也是最常见的一种,就是多个线程使用ThreadLocal 第二种,类加载器不同造成取不到值,本质原因就是不同类加载器造成多个ThreadLocal对象 public class StaticClassLoaderTest { protected static final ThreadLocal<Object> local = new ThreadLocal<Object>(); //cusLoader加载器加载的对象 private Test3 test3;

  • java中synchronized Lock(本地同步)锁的8种情况

    目录 lock1 lock2 lock3 lock4 lock5 lock6 lock7 lock8 Lock(本地同步)锁的8种情况总结与说明: * 题目: * 1.标准访问,请问是先打印邮件还是短信 Email * 2.email方法新增暂停4秒钟,请问是先打印邮件还是短信 Email * 3.新增普通的hello方法,请问先打印邮件还是hello hello * 4.两部手机,请问先打印邮件还是短信 SMS * 5.两个静态同步方法,1部手机,请问先打印邮件还是短信 Email * 6.两

  • 浅谈Java中Collections.sort对List排序的两种方法

    目录 一.Collections.sort的简单使用 二.问题提出 三.Comparable实现排序 四.Comparator实现排序 五.Comparable 与Comparator区别 一.Collections.sort的简单使用 说到List的排序,第一反应当然是使用Collections.sort,方便简单.下面实现一下~~ private void sortStrings() { List<String> list = new ArrayList<String>();

随机推荐