当前位置:网站首页>实战小技巧19:List转Map List的几种姿势
实战小技巧19:List转Map List的几种姿势
2022-08-10 05:09:00 【小灰灰Blog】
今天介绍一个实用的小知识点,如何将List转为Map<Object, List<Object>>
<!-- more -->
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]}
一灰灰的联系方式
尽信书则不如无书,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
- 个人站点:https://blog.hhui.top
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840
- 微信公众号:一灰灰blog
边栏推荐
- ThreadPoolExecutor线程池原理
- pytorch learning
- 大佬们,mysql cdc(2.2.1跟之前的版本)从savepoint起有时出现这种情况,有没有什
- 剑指Offer 033.变位数组
- 栈与队列 | 有效的括号、删除字符串中的所有相邻元素、逆波兰表达式求值、滑动窗口的最大值、前K个高频元素 | leecode刷题笔记
- Nexus_仓库类型
- aliases节点分析
- canvas 画布绘制时钟
- 2022 security officer C certificate test and simulation test in shandong province
- Nexus_Warehouse Type
猜你喜欢
万字总结:分布式系统的38个知识点
2022 security officer C certificate test and simulation test in shandong province
Hezhou ESP32C3 +1.8"tft network clock under Arduino framework
【论文笔记】Prototypical Contrast Adaptation for Domain Adaptive Semantic Segmentation
Unity implements UI edge detection and drag-and-drop functions
leetcode每天5题-Day12
MySQL simple tutorial
Stacks and Queues | Valid parentheses, delete all adjacent elements in a string, reverse Polish expression evaluation, maximum sliding window, top K high frequency elements | leecode brush questions
暑期学前作业
西门子Step7和TIA软件“交叉引用”的使用
随机推荐
Ueditor editor arbitrary file upload vulnerability
LeetCode 301. Remove Invalid Parentheses BFS
如何从代码层提高产品质量
Thread.sleep, Thread.yield role explanation
什么是“大小端字节序”存储模式?
`id` bigint(20) unsigned NOT NULL COMMENT '数据库主键',
mysql常用命令有什么
华为交换机配置日志推送
Promise原理及实现
转型做产品,考NPDP靠谱吗?
leetcode每天5题-Day13
LeetCode·124.二叉树中的最大路径和·递归
Shell编程三剑客之awk
Unity implements UI edge detection and drag-and-drop functions
oracle rac 11g安装执行root.sh时报错
Guys, is it normal that the oracle archive log grows by 3G in 20 minutes after running cdc?
【Pei Shu Theorem】CF1055C Lucky Days
Depth of carding: prevent model fitting method
Rpc interface stress test
From entry to mastery of PHPCMS imitation station, Xiaobai is enough to watch this set of courses