Today, I will introduce a practical little knowledge point, how to convert List to Map<Object, List<Object>>
<!-- more -->
1. Basic writing
The first introduction is of course the most common and intuitive way of writing, and of course any restricted way of writing
// 比如将下面的列表,按照字符串长度进行分组
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);
For jdk8+, the content in the above for loop can be replaced by Map.computeIfAbsent
, the specific writing is as follows
for (String str : list) {
ans.computeIfAbsent(str.length(), k -> new ArrayList<>()).add(str);
}
Of course, since it is already jdk1.8, with the stream processing of Stream, the above step can be simplified, as follows
Map<Integer, List<String>> ans = list.stream().collect(Collectors.groupingBy(String::length));
2. General approach
The above is for a specific list, for business development and transformation, then we will try to build a general tool class next
The knowledge point we mainly use here is generics, and an important point is how to get the key in the Map
For the writing method of jdk < 1.8, the acquisition posture of the key is defined through the interface
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);
}
Use the demo as follows
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);
}
Next, let's take a look at the writing method after jdk1.8, combined with stream + function method to achieve
public static <K, V> Map<K, List<V>> toMapList(List<V> list, Function<V, K> func) {
return list.stream().collect(Collectors.groupingBy(func));
}
The corresponding usage is as follows
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);
}
- Tools
The previous section introduced the implementation of generic conversion tool classes based on generics + jdk8 Stream + function methods. Next, let's summarize and output a tool class suitable for 1.8 and later.
/**
* 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 extended knowledge points
Finally, an extended knowledge point is introduced. The Gauva toolkit provides a tool class HashMultimap
. Its usage posture is no different from our usual Map, but it should be noted that its value is a gather
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);
The actual output is as follows, which verifies that the value is actually a set (there is only one on, if it is our tool class above, it will output two)
{2=[on], 4=[word, come], 5=[hello]}
A grey contact
It is better to have no books than no books. The above content is purely from one family. Due to limited personal ability, there are inevitably omissions and mistakes. If you find bugs or have better suggestions, you are welcome to criticize and correct them. Thank you
- Personal site: https://blog.hhui.top
- Weibo address: Xiaohuihui Blog
- QQ: A gray gray / 3302797840
- WeChat public account: a gray blog
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。