java 将list转换为map 的泛型通用方法

来源:互联网 发布:ssh 指定端口号 编辑:程序博客网 时间:2024/06/02 06:25

将list转换为map

背景:最近使用比较多的mongodb,由于其缺乏表连接的查询,导致我们经常需要将表数据查询到内存中,然后进行匹配连接,组成需要的数据格式,匹配的方式通常是:

list1中有list2需要的字段,于是将list1转换为map,遍历list2,从map中找到对应的数据字段。当面对大量的这样的业务操作的时候,一个个写将list转换为map的小代码段,是非常浪费时间,容易出错且无益的,所以抽时间将这个方法写下来,以便以后使用。

本人在写这个方法的时候,只改进过一次,执行效率上和原始的转换代码效率差距不大了,是可以使用的方法了

1、首先是list里面的bean 没什么好说的

public static class DemoClass{private Integer id;private String name;public DemoClass(){}public DemoClass(Integer id, String name) {super();this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
2、传统的转换方法

public static Map<Integer, DemoClass> traditionalWay(List<DemoClass> list) {Map<Integer, DemoClass> map = new HashMap<Integer, DemoClass>();if (list != null) {for (int i = 0; i < list.size(); i++) {DemoClass value = list.get(i);map.put(value.getId(), value);}}return map;}

下面来实现通用接口

3、由于我们通常需要转换的时候,需要将其中一个属性作为key,整个对象(或者其中一个属性,方法类似,自己去拓展)作为value构成map

 方法名为

public static <K, V> Map<K, V> list2Map(List<V> list, String fieldName4Key);

4、工程引入jar包,不是所有的jar包都要包含,像dom4j就不需要

5、版本一:我们写这个方法的时候无法获得bean的get方法,首先想到使用内省机制去实现,commons-beanutils提供了获得属性名对应的get方法,代码如下

public static <K, V> Map<K, V> list2Map1(List<V> list, String fieldName4Key) {Map<K, V> map = new HashMap<K, V>();if (list != null) {try {for (int i = 0; i < list.size(); i++) {V value = list.get(i);@SuppressWarnings("unchecked")K k = (K) BeanUtils.getProperty(value, fieldName4Key);map.put(k, value);}} catch (Exception e) {throw new IllegalArgumentException("field can't match the key!");}}return map;}

经测试(main方法里面的时间是测试结果):效率很低,多次调用了beanUtils.getProperty严重降低了方法的效率。因此需要找一个替代的方法,比如直接获得get方法,因此版本二诞生了。

6、版本二:

       /**     * transfer list into map     * @param list     * @param fieldName4Key     * @return map     *      * @author sherlock     * @date 2016-9-16 12:58:53     */    public static <K, V> Map<K, V> list2Map2(List<V> list, String fieldName4Key,Class<V> c) {        Map<K, V> map = new HashMap<K, V>();        if (list != null) {            try {                PropertyDescriptor propDesc = new PropertyDescriptor(fieldName4Key, c);                Method methodGetKey = propDesc.getReadMethod();                for (int i = 0; i < list.size(); i++) {                    V value = list.get(i);                    @SuppressWarnings("unchecked")                    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;    }
测试结果比较满意,效率上与一般的转换方式差距不大。

也可以通过方法名获得method,因为它们都是先获得方法,效率区别不大,优点是当你需要复杂的规则去组成key或者value的时候,可以调用自定义的方法,更加灵活,示例代码

    public static <K, V> Map<K, V> list2Map3(List<V> list, String keyMethodName,Class<V> c) {        Map<K, V> map = new HashMap<K, V>();        if (list != null) {            try {                Method methodGetKey = c.getMethod(keyMethodName);                for (int i = 0; i < list.size(); i++) {                    V value = list.get(i);                    @SuppressWarnings("unchecked")                    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;    }

7、以下是整个类,以及测试结果,测试结果在每个方法调用的注释里

package test;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.commons.beanutils.BeanUtils;public class ListToMap {    public static class DemoClass{        private Integer id;        private String name;        public DemoClass(){}        public DemoClass(Integer id, String name) {            super();            this.id = id;            this.name = name;        }        public Integer getId() {            return id;        }        public void setId(Integer id) {            this.id = id;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        }        public static <K, V> Map<K, V> list2Map1(List<V> list, String fieldName4Key) {        Map<K, V> map = new HashMap<K, V>();        if (list != null) {            try {                for (int i = 0; i < list.size(); i++) {                    V value = list.get(i);                    @SuppressWarnings("unchecked")                    K k = (K) BeanUtils.getProperty(value, fieldName4Key);                    map.put(k, value);                }            } catch (Exception e) {                throw new IllegalArgumentException("field can't match the key!");            }        }        return map;    }    /**     * transfer list into map     * @param list     * @param fieldName4Key     * @return map     *      * @author sherlock     * @date 2016-9-16 12:58:53     */    public static <K, V> Map<K, V> list2Map2(List<V> list, String fieldName4Key,Class<V> c) {        Map<K, V> map = new HashMap<K, V>();        if (list != null) {            try {                PropertyDescriptor propDesc = new PropertyDescriptor(fieldName4Key, c);                Method methodGetKey = propDesc.getReadMethod();                for (int i = 0; i < list.size(); i++) {                    V value = list.get(i);                    @SuppressWarnings("unchecked")                    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;    }        public static <K, V> Map<K, V> list2Map3(List<V> list, String keyMethodName,Class<V> c) {        Map<K, V> map = new HashMap<K, V>();        if (list != null) {            try {                Method methodGetKey = c.getMethod(keyMethodName);                for (int i = 0; i < list.size(); i++) {                    V value = list.get(i);                    @SuppressWarnings("unchecked")                    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;    }    public static Map<Integer, DemoClass> traditionalWay(List<DemoClass> list) {        Map<Integer, DemoClass> map = new HashMap<Integer, DemoClass>();        if (list != null) {            for (int i = 0; i < list.size(); i++) {                DemoClass value = list.get(i);                map.put(value.getId(), value);            }        }        return map;    }    public static void main(String[] args) throws Exception{        List<DemoClass> list = new ArrayList<>();        for (int i = 0; i < 1000000; i++) {            list.add(new DemoClass(i,"aaa"));        }        long start1 = System.nanoTime();        //list2Map1(list,"id");  //2265651285        list2Map2(list,"id",DemoClass.class); //95193405          //list2Map3(list,"getId",DemoClass.class);        //Map<Integer,DemoClass> map = traditionalWay(list); //75825131        long end1 = System.nanoTime();                System.out.println(end1 - start1);    }}


list2Map2(...),list2Map3(...)都是可取的,区别是list2Map3(...)比较灵活

转载需要注明出处,谢谢~~



0 0
原创粉丝点击