将List转化为Map的通用方法—泛型方法的简单运用

有时候我们需要将List转化为Map,将数据散列存储,以提高查询效率。但是集合类中所存放的对象类型是不同的,因此,针对不同类型,我们常会写多个逻辑重复的转化方法,如:

 public static Map<Integer, Person> listPersonToMap(List<Person> vList) {
  //转化代码
  Map<Integer, Person> map = new HashMap<Integer, Person>();
  for(Person p:vList){
   map.put(p.getUserId(), p);
  }
  return map;
 }
 public static Map<String, Dog> listDogToMap(List<Dog> vList) {
  //转化代码
  Map<String, Dog> map = new HashMap<String, Dog>();
  for(Dog d:vList){
   map.put(d.getDogCode(), d);
  }
  return map;
 }

重复劳动是程序员的天敌,程序员的任务就是尽一切可能消除这些繁琐的体力劳动,实现自动化,这里,我们可以自定义一个泛型方法,一劳永逸。自定义泛型方法时,只要在方法返回值前面使用<>声明泛型类型,则在返回值,参数,方法体内都可以使用该泛型类型。

//list转化为map
 public static <K, V> Map<K, V> listToMap(List<V> vList, String kName) {
  Map<K, V> map = new HashMap<K, V>();
  if (vList == null || kName == null || vList.size() == 0) {
   return map;
  }
  Field kField = getField(vList.get(0).getClass(), kName);
  for (V v : vList) {
   try {
    map.put((K) kField.get(v), v);
   } catch (IllegalArgumentException e) {
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    e.printStackTrace();
   }
  }
  return map;
 }

在转化过程中,key对应的字段类型和名称需要动态获取,我们传入kName参数,并利用Class#getDeclaredFields()获取字段并循环比较java.lang.reflect.Field#getName()字段名称,返回其类型对象,如下:

//获取key对应的类型字段
 private static <V> Field getField(Class<V> clazz, String kName) {
  if (clazz == null || kName == null) {
   return null;
  }
  for (Field fieldElem : clazz.getDeclaredFields()) {
   fieldElem.setAccessible(true);
   if (fieldElem.getName().equals(kName)) {
    return fieldElem;
   }
  }
  return null;
 }
//调用示例
 public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
  List<Person> pList = new ArrayList<Person>();
  Person p1 = new Person(2, "taxuexing");
  pList.add(p1);
  Person p2 = new Person(3, "jikewang");
  pList.add(p2);
  Map<Integer, Person> map = MapUtil.listToMap(pList, "userId");
  System.out.println(map.get(2).getUserName());
  System.out.println(map.get(3).getUserName());
 }
}

输出:

taxuexing

jikewang

反射技术毕竟对性能有一定影响,有更好的实现方式的伙伴欢迎留言。

原文发布于微信公众号 - java达人(drjava)

原文发表时间:2016-04-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据钻研

JavaScript 知识点整理

JavaScript是按照ECMAScript标准设计和实现的,后文说的JavaScript语法其实是ES5的标准的实现。 先说说有哪些基础语法? 最基础语法有...

2845
来自专栏拭心的安卓进阶之路

深入理解 Java 反射:Method (成员方法)

深入理解 Java 反射系列: 深入理解 Java 反射:Class (反射的入口) 深入理解 Java 反射:Field (成员变量) 深入理解 Java ...

3957
来自专栏mukekeheart的iOS之旅

《JavaScript高级程序设计》学习笔记(5)——面向对象编程

 欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。   本节内容对应《JavaScript高级程序设计》的第六章内容。 1、面向对象...

2879
来自专栏彭湖湾的编程世界

【算法】实现栈和队列

栈(stack) 栈(stack)是一种后进先出(LIFO)的集合类型, 即后来添加的数据会先被删除 ? 可以将其类比于下面文件的取放操作:新到的文件会被先取走...

3456
来自专栏开发与安全

从零开始学C++之标准库类型(二):vector 类简介和例程

一、标准库的vector类型 vector是同一种类型的对象的集合 vector的数据结构很像数组,能非常高效和方便地访问单个元素 vector是一个类模板...

1940
来自专栏GreenLeaves

JavaScript之面向对象的概念,对象属性和对象属性的特性简介

  一、大家都知道,面向对象语言有一个标志,那就是他们都有类的概念,通过类我们可以创建任意多个具有相同属性和方法的对象。但ECMAScript(指定JavaSc...

1756
来自专栏java初学

5.7(1) 反射

31411
来自专栏Ryan Miao

在Springmvc中获取properties属性

一些关键的属性一般都会拿出来作为配置,比如数据库连接等。在springmvc中也提供了获取property的类,比如@Value来获取。我接触spring很浅,...

4629
来自专栏jessetalks

Javascript基础回顾 之(三) 面向对象

Javascript中的对象 什么是对象   我们可以把Javascript中对象理解为一组无序的键值对,就好像C#中的Dictionary<string,O...

33611
来自专栏信数据得永生

JavaScript 编程精解 中文第三版 六、对象的秘密

3016

扫码关注云+社区

领取腾讯云代金券