JAVA集合转map的几种方法
1 基本写法
// 按照字符串长度分组 List<String> list = new ArrayList<>(); list.add("1111"); list.add("2222"); list.add("3333"); list.add("44"); 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. 通用方法
使用泛型封装:
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); }
public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("1111"); list.add("2222"); list.add("3333"); list.add("444"); Map<Integer, List<String>> res = toMapList(list, new KeyFunc<String, Integer>() { @Override public Integer getKey(String s) { return s.length(); } }); System.out.println(res); }
3. 封装工具类
** * 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()))); }
应用代码:
public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("1111"); list.add("2222"); list.add("3333"); list.add("444"); Map<Integer, List<String>> res = toMapList(list, new Function<String,Integer>() { @Override public Integer apply(String o) { return o.length(); } }); System.out.println(res); }
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1111");
list.add("2222");
list.add("3333");
list.add("444");
Map<Integer, List<String>> res = toMapList(list, String::length); //简单写法
System.out.println(res);
}
输出结果:
{3=[444], 4=[1111, 2222, 3333]}
3. 扩展知识点
最后再介绍一个扩展知识点,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: list) { map.put(item.length(), item); } System.out.println(map);
实际输出如下,验证了value实际上是个集合(on只有一个,如果是我们上面的工具类,会输出两个)
{2=[on], 4=[word, come], 5=[hello]}
Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear.
面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!