Java List Object[]转换成List T的实例
一)背景
主要是为了实现数据之间的转换,方便数据展示。
使用场景:当数据可能是list<object[]>类型,可能会需要转换成具体的list<class>格式。
二)list<object[]>转换成list<t>
功能:传入list<object[]>数据和需要转换的class对象,返回一个list<class>数据集合
实现方式:java反射方式,使用的是构造器的方式
缺点:实体类中必须有无参数构造器,有参数构造器,且构造器参数的顺序和数据的顺序必须一致。如果数据格式有变化,需要重新编写一个实体类的构造器
实现源码:
package com.oysept.utils; import java.lang.reflect.constructor; import java.util.arraylist; import java.util.list; /** * list<object[]>转换成一个list<t> * @author ouyangjun */ public class objecttobeanutils { /** * 把list<object[]>转换成list<t> */ public static <t> list<t> objecttobean(list<object[]> objlist, class<t> clz) throws exception{ if (objlist==null || objlist.size()==0) { return null; } class<?>[] cz = null; constructor<?>[] cons = clz.getconstructors(); for (constructor<?> ct : cons) { class<?>[] clazz = ct.getparametertypes(); if (objlist.get(0).length == clazz.length) { cz = clazz; break; } } list<t> list = new arraylist<t>(); for (object[] obj : objlist) { constructor<t> cr = clz.getconstructor(cz); list.add(cr.newinstance(obj)); } return list; } }
三)实体类phonevo.java
package com.oysept.bean; import java.io.serializable; import java.math.bigdecimal; public class phoneentity implements serializable { private static final long serialversionuid = 1l; public phoneentity() {} /** * 构造器 * 注意: 实体类中必须有无参数构造器,有参数构造器,且构造器参数的顺序和数据的顺序必须一致。如果数据格式有变化,需要重新编写一个实体类的构造器 */ public phoneentity(string plate, bigdecimal number, double memory, double size) { super(); this.plate = plate; this.number = string.valueof(number); this.memory = string.valueof(memory); this.size = string.valueof(size); } private string plate; private string number; private string memory; private string size; public string getplate() { return plate; } public void setplate(string plate) { this.plate = plate; } public string getnumber() { return number; } public void setnumber(string number) { this.number = number; } public string getmemory() { return memory; } public void setmemory(string memory) { this.memory = memory; } public string getsize() { return size; } public void setsize(string size) { this.size = size;} }
四)数据转换测试类
package com.oysept.test; import java.math.bigdecimal; import java.util.arraylist; import java.util.list; import com.oysept.bean.phoneentity; import com.oysept.utils.objecttobeanutils; /** * 测试类 * @author ouyangjun */ public class objecttobeantest { public static void main(string[] args) throws exception { // 初始化数据 object[] obj = new object[4]; obj[0] = "hw"; obj[1] = bigdecimal.valueof(13699999999l); obj[2] = 4.7; obj[3] = 5.0; object[] obj1 = new object[4]; obj1[0] = "vivo"; obj1[1] = bigdecimal.valueof(13611111111l); obj1[2] = 4.8; obj1[3] = 5.7; list<object[]> objlist = new arraylist<object[]>(); objlist.add(obj); objlist.add(obj1); // 工具类 list<phoneentity> list = objecttobeanutils.objecttobean(objlist, phoneentity.class); for (phoneentity phone : list) { system.out.println(phone.getplate() + "\t" + phone.getnumber() + "\t" + phone.getmemory() + "\t" + phone.getsize()); } } }
数据转换打印效果图:
补充知识:list、list<object>、list<?>的区别
通过一个例子来比较这几种写法的区别
public class listwithoutgeneric { public static void main(string[] args) { // 第一段:不使用泛型的方式 list a1 = new arraylist(); a1.add(new object()); a1.add(new integer(1)); a1.add(new string("a1")); // 第二段:把a1赋值给list<object>类型的a2,看似a2与a1没有区别 list<object> a2 = a1; a2.add(new object()); a2.add(new integer(2)); a2.add(new string("a2")); // 但是如果尝试把一个带有其它类型泛型的b2赋值给a2,则会编译报错 list<string> b2 = new arraylist<>(); // 编译报错,这也是list与list<object>的区别 a2 = b2; // 第三段:把a1赋值给list<integer>类型的a3,赋值过程没有编译报错,主要为了向前兼容(泛型jdk1.5之后才出现) list<integer> a3 = a1; a3.add(new integer(3)); // java.lang.classcastexception: java.lang.object cannot be cast to java.lang.integer integer integer = a3.get(0); // 编译报错,不允许add非integer类型 a3.add(new object()); a3.add(new string("a3")); // 第四段:把a1赋值给list<?>类型的a4 list<?> a4 = a1; a4.remove(0); a4.clear(); a4.add(null); // 编译出错,不允许add非null的数据 a4.add(new object()); } }
1、第一段:定义了一个没使用泛型的list a1,向a1中添加不同类型的元素,所有功能都可以正常使用,但使用时会有类型强制转换异常的风险。
2、第二段:把a1赋值给list<object>类型的a2,再往a2添加不同类型元素,不会编译报错,看似a2与a1没有区别,但是如果尝试把一个带有其它类型泛型(list<string>)的b2赋值给a2,则会编译报错,除非让泛型保持一致。
这也是list与list<object>的区别:泛型之间只有同类型才能相互赋值。
3、第三段:把a1赋值给list<integer>类型的a3,赋值过程没有编译报错,主要为了向前兼容(泛型jdk1.5之后才出现),但如果直接用integer类型取值,会报类型转换异常。因为a3有了泛型约束,再添加其它类型元素,则会编译报错。
4、list<?>是通配符集合,一般作为参数来接收外部的集合,或者返回一个不知道具体元素类型的集合。它可以被任何类型的集合引用赋值,也可以删除元素。但是因为类型的不确定,所有不能添加非null元素(null属于任何类型)。
以上内容根据《码出高效java开发手册》学习整理。希望能给大家一个参考,也希望大家多多支持。
推荐阅读