Habilidades básicas de Java: varias posturas de List to Map List

¡Continúe creando, acelere el crecimiento! Este es el 4to día de mi participación en el "Nuggets Daily New Plan · June Update Challenge", haz clic para ver los detalles del evento

Hoy, presentaré un pequeño punto de conocimiento práctico, cómo convertir List aMap<Object, List<Object>>

1. Escritura básica

La primera introducción es, por supuesto, la forma de escritura más común e intuitiva y, por supuesto, cualquier forma de escritura restringida.

// 比如将下面的列表,按照字符串长度进行分组
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);
复制代码

Para jdk8+, el contenido del bucle for anterior se Map.computeIfAbsentpuede reemplazar con lo siguiente:

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

Por supuesto, dado que ya es jdk1.8, con la ayuda del procesamiento de flujo de Stream, el paso anterior se puede simplificar de la siguiente manera

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

2. Enfoque general

Lo anterior es para una lista específica, para el desarrollo y la transformación empresarial, luego tratamos de construir una clase de herramienta general a continuación

El punto de conocimiento que usamos principalmente aquí es genérico, y un punto importante es cómo obtener la clave en el Mapa

Para el método de escritura de jdk < 1.8, la postura de adquisición de la clave se define a través de la interfaz

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 la demostración de la siguiente manera

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);
}
复制代码

A continuación, echemos un vistazo al método de escritura después de jdk1.8, combinado con el método de flujo + función para lograr

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

El uso correspondiente es el siguiente

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. Herramientas

La sección anterior presentó la implementación de clases de herramientas de conversión genéricas basadas en métodos genéricos + jdk8 Stream + función A continuación, resumamos y generemos una clase de herramienta adecuada para 1.8 y versiones posteriores.

/**
 * 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.Puntos de conocimiento extendido Guava HashMultimap

Finalmente, se introduce un punto de conocimiento ampliado. El conjunto de herramientas de Gauva proporciona una HashMultimapclase de herramienta. Su postura de uso no es diferente de nuestro Mapa habitual, pero debe tenerse en cuenta que su valor es una colección.

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);
复制代码

El resultado real es el siguiente, que verifica que el valor es realmente un conjunto (solo hay uno, si es nuestra clase de herramienta anterior, generará dos)

{2=[on], 4=[word, come], 5=[hello]}
复制代码

un contacto gris

Es mejor no tener libros que no tener libros. El contenido anterior es puramente de una familia. Debido a la capacidad personal limitada, inevitablemente hay omisiones y errores. Si encuentra errores o tiene mejores sugerencias, puede criticarlas y corregirlas. . Gracias

Supongo que te gusta

Origin juejin.im/post/7104267494537297933
Recomendado
Clasificación