List to Map

368 阅读2分钟

场景

工作中,经常会使用不同的数据结构来应对繁杂的业务处理,如:list转map……

本文整理了如下几种list结构到map结构的转换方法:

  • List<Object>Map<String, Object>
  • List<Object>Map<String, String>
  • List<Object>Map<String, List<Object>>
  • List<Object>Map<String, List<String>>

测试实体

public class DictCode
{
    private String codeKey;
    private String codeValue;

    public DictCode(String codeKey, String codeValue)
    {
        this.codeKey = codeKey;
        this.codeValue = codeValue;
    }

    public DictCode()
    {
    }

    public String getCodeKey()
    {
        return codeKey;
    }

    public void setCodeKey(String codeKey)
    {
        this.codeKey = codeKey;
    }

    public String getCodeValue()
    {
        return codeValue;
    }

    public void setCodeValue(String codeValue)
    {
        this.codeValue = codeValue;
    }

    @Override
    public String toString()
    {
        return "DictCode{" + "codeKey='" + codeKey + ''' + ", codeValue='" + codeValue + ''' + '}';
    }
}

List<Object>Map<String, Object>

方法一:封装工具

/**
 * List转Map
 * @param list 源List集合
 * @param keyMethodName 返回map的键的get方法名称
 * @param clazz 返回Map的Value的class对象
 * @return
 */
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> listToMap(List<V> list, String keyMethodName, Class<V> clazz)
{
    Map<K, V> map = new LinkedHashMap<K, V>();
    if (list != null)
    {
        try
        {
            Method methodGetKey = clazz.getMethod(keyMethodName);
            for (int i = 0; i < list.size(); i++)
            {
                V value = list.get(i);
                K key = (K) methodGetKey.invoke(list.get(i));
                map.put(key, value);
            }
        } catch (Exception e)
        {
            throw new IllegalArgumentException("field can't match the key!");
        }
    }
    return map;
}

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试:key相同时,后面的自动覆盖前面的
    Map<String, DictCode> map = listToMap(list, "getCodeKey", DictCode.class);
    for (Map.Entry<String, DictCode> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:兼容null
    //        key=null, value=DictCode{codeKey='null', codeValue='1'}
    //        key=2, value=DictCode{codeKey='2', codeValue='2'}
    //        key=3, value=DictCode{codeKey='3', codeValue='4'}
}

方法二:流式处理

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试3:参数一(map的key)、参数二(map的value)、参数三(key相同时的覆盖策略,此处策略:以第一个key为准,抛弃后续相同key)
    Map<String, DictCode> map = list.stream()
            .collect(Collectors.toMap(DictCode::getCodeKey, Function.identity(), (k1, k2) -> k1));
    /*Map<String, DictCode> map_2 = list.stream()
        .collect(Collectors.toMap(DictCode::getCodeKey, y -> y, (k1, k2) -> k1));*/
    for (Map.Entry<String, DictCode> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:兼容null
    //        key=null, value=DictCode{codeKey='null', codeValue='1'}
    //        key=2, value=DictCode{codeKey='2', codeValue='2'}
    //        key=3, value=DictCode{codeKey='3', codeValue='3'}
}

List<Object>Map<String, String>

流式处理

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试:参数一(map的key)、参数二(map的value)、参数三(key相同时的覆盖策略,此处策略:以第一个key为准,抛弃后续相同key)
    Map<String, String> map = list.stream()
            .collect(Collectors.toMap(DictCode::getCodeKey, y -> y.getCodeValue(), (k1, k2) -> k1));
    for (Map.Entry<String, String> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:兼容null
    //        key=null, value=1
    //        key=2, value=2
    //        key=3, value=3
}

List<Object>Map<String, List<Object>>

方法一:封装工具

/**
 * List转Map
 * @param list 源List集合
 * @param keyMethodName 返回map的键的get方法名称
 * @param clazz 返回Map的Value的class对象
 * @return
 */
@SuppressWarnings("unchecked")
public static <K, V> Map<K, List<V>> list2Map(List<V> list, String keyMethodName, Class<V> clazz)
{
    Map<K, List<V>> map = new LinkedHashMap<K, List<V>>();
    if (!CommonUtil.isEmpty(list))
    {
        try
        {
            Method methodGetKey = clazz.getMethod(keyMethodName);
            for (int i = 0; i < list.size(); i++)
            {
                V value = list.get(i);
                K key = (K) methodGetKey.invoke(list.get(i));
                List<V> vList = map.get(key);
                if (CommonUtil.isEmpty(vList))
                {
                    vList = new ArrayList<V>();
                    vList.add(value);
                } else
                {
                    vList.add(value);
                }
                map.put(key, vList);
            }
        } catch (Exception e)
        {
            throw new IllegalArgumentException("field can't match the key!");
        }
    }
    return map;
}

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试:key相同时,将值构建为集合返回
    Map<String, List<DictCode>> map = list2Map(list, "getCodeKey", DictCode.class);
    for (Map.Entry<String, List<DictCode>> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:兼容null
    //        key=null, value=[DictCode{codeKey='null', codeValue='1'}]
    //        key=2, value=[DictCode{codeKey='2', codeValue='2'}]
    //        key=3, value=[DictCode{codeKey='3', codeValue='3'}, DictCode{codeKey='3', codeValue='4'}]
}

方法二:流式处理

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试:key相同时,将值构建为集合返回,不兼容null,因此先要对获取的key值进行过滤,否则报错
    Map<String, List<DictCode>> map = list.stream().filter(x -> null != x.getCodeKey())
            .collect(Collectors.groupingBy(DictCode::getCodeKey));
    for (Map.Entry<String, List<DictCode>> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:因key为null的元素被过滤,故转换的map中不包含key=null的元素
    //        key=2, value=[DictCode{codeKey='2', codeValue='2'}]
    //        key=3, value=[DictCode{codeKey='3', codeValue='3'}, DictCode{codeKey='3', codeValue='4'}]
}

List<Object>Map<String, List<String>>

流式处理

/**
 * 测试代码
 * @param args
 */
public static void main(String[] args)
{
    List<DictCode> list = new ArrayList<>();
    list.add(new DictCode(null, "1"));
    list.add(new DictCode("2", "2"));
    list.add(new DictCode("3", "3"));
    list.add(new DictCode("3", "4"));

    // 测试:key相同时,将值构建为集合返回,不兼容null,因此先要对获取的key值进行过滤,否则报错
    Map<String, List<String>> map = list.stream().filter(x -> null != x.getCodeKey()).collect(Collectors
            .groupingBy(DictCode::getCodeKey, Collectors.mapping(DictCode::getCodeValue, Collectors.toList())));
    for (Map.Entry<String, List<String>> entry : map.entrySet())
    {
        System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
    }
    // 打印结果:因key为null的元素被过滤,故转换的map中不包含key=null的元素
    //        key=2, value=[2]
    //        key=3, value=[3, 4]
}