Java基本功:List转Map List的几种姿势

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]}
全部评论

相关推荐

点赞 评论 收藏
分享
刚刷到字节跳动官方发的消息,确实被这波阵仗吓了一跳。在大家还在纠结今年行情是不是又“寒冬”的时候,字节直接甩出了史上规模最大的转正实习计划——ByteIntern。咱们直接看几个最硬的数,别被花里胡哨的宣传词绕晕了。首先是“量大”。全球招7000多人是什么概念?这几乎是把很多中型互联网公司的总人数都给招进来了。最关键的是,这次的资源分配非常精准:研发岗给了4800多个Offer,占比直接超过六成。说白了,字节今年还是要死磕技术,尤其是产品和AI领域,这对于咱们写代码的同学来说,绝对是今年最厚的一块肥肉。其次是大家最关心的“转正率”。官方直接白纸黑字写了:整体转正率超过50%。这意味着只要你进去了,不划水、正常干,每两个人里就有一个能直接拿校招Offer。对于2027届(2026年9月到2027年8月毕业)的同学来说,这不仅是实习,这简直就是通往大厂的快捷通道。不过,我也得泼盆冷水。坑位多,不代表门槛低。字节的实习面试出了名的爱考算法和工程实操,尤其是今年重点倾斜AI方向,如果你简历里有和AI相关的项目,优势还是有的。而且,转正率50%也意味着剩下那50%的人是陪跑的,进去之后的考核压力肯定不小。一句话总结:&nbsp;27届的兄弟们,别犹豫了。今年字节这是铁了心要抢提前批的人才,现在投递就是占坑。与其等到明年秋招去千军万马挤独木桥,不如现在进去先占个工位,把转正名额攥在手里。
喵_coding:别逗了 50%转正率 仔细想想 就是转正与不转正
字节7000实习来了,你...
点赞 评论 收藏
分享
03-13 14:21
已编辑
江西警察学院 前端工程师
站队站对牛:红红一大片 天都要塌了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务