Java List Object[]轉(zhuǎn)換成List T的實例
一)背景
主要是為了實現(xiàn)數(shù)據(jù)之間的轉(zhuǎn)換,方便數(shù)據(jù)展示。
使用場景:當數(shù)據(jù)可能是List<Object[]>類型,可能會需要轉(zhuǎn)換成具體的List<Class>格式。
二)List<Object[]>轉(zhuǎn)換成List<T>
功能:傳入List<Object[]>數(shù)據(jù)和需要轉(zhuǎn)換的Class對象,返回一個List<Class>數(shù)據(jù)集合
實現(xiàn)方式:Java反射方式,使用的是構(gòu)造器的方式
缺點:實體類中必須有無參數(shù)構(gòu)造器,有參數(shù)構(gòu)造器,且構(gòu)造器參數(shù)的順序和數(shù)據(jù)的順序必須一致。如果數(shù)據(jù)格式有變化,需要重新編寫一個實體類的構(gòu)造器
實現(xiàn)源碼:
package com.oysept.utils;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
/**
* List<Object[]>轉(zhuǎn)換成一個List<T>
* @author ouyangjun
*/
public class ObjectToBeanUtils {
/**
* 把List<Object[]>轉(zhuǎn)換成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() {}
/**
* 構(gòu)造器
* 注意: 實體類中必須有無參數(shù)構(gòu)造器,有參數(shù)構(gòu)造器,且構(gòu)造器參數(shù)的順序和數(shù)據(jù)的順序必須一致。如果數(shù)據(jù)格式有變化,需要重新編寫一個實體類的構(gòu)造器
*/
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;}
}
四)數(shù)據(jù)轉(zhuǎn)換測試類
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 {
// 初始化數(shù)據(jù)
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());
}
}
}
數(shù)據(jù)轉(zhuǎn)換打印效果圖:

補充知識:List、List<Object>、List<?>的區(qū)別
通過一個例子來比較這幾種寫法的區(qū)別

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沒有區(qū)別
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>的區(qū)別
a2 = b2;
// 第三段:把a1賦值給List<Integer>類型的a3,賦值過程沒有編譯報錯,主要為了向前兼容(泛型jdk1.5之后才出現(xiàn))
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的數(shù)據(jù)
a4.add(new Object());
}
}
1、第一段:定義了一個沒使用泛型的List a1,向a1中添加不同類型的元素,所有功能都可以正常使用,但使用時會有類型強制轉(zhuǎn)換異常的風險。
2、第二段:把a1賦值給List<Object>類型的a2,再往a2添加不同類型元素,不會編譯報錯,看似a2與a1沒有區(qū)別,但是如果嘗試把一個帶有其它類型泛型(List<String>)的b2賦值給a2,則會編譯報錯,除非讓泛型保持一致。
這也是List與List<Object>的區(qū)別:泛型之間只有同類型才能相互賦值。
3、第三段:把a1賦值給List<Integer>類型的a3,賦值過程沒有編譯報錯,主要為了向前兼容(泛型jdk1.5之后才出現(xiàn)),但如果直接用Integer類型取值,會報類型轉(zhuǎn)換異常。因為a3有了泛型約束,再添加其它類型元素,則會編譯報錯。
4、List<?>是通配符集合,一般作為參數(shù)來接收外部的集合,或者返回一個不知道具體元素類型的集合。它可以被任何類型的集合引用賦值,也可以刪除元素。但是因為類型的不確定,所有不能添加非null元素(null屬于任何類型)。
以上內(nèi)容根據(jù)《碼出高效Java開發(fā)手冊》學(xué)習整理。希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于解決iReport4.1.1無法正常啟動或者閃退或者JDK8不兼容的問題
在安裝使用iReport的過程中遇到一個問題,我的iReport始終不能打開,困擾了我好久。接下來通過本文給大家介紹iReport4.1.1無法正常啟動或者閃退或者JDK8不兼容的問題,需要的朋友可以參考下2018-09-09
spring的TransactionSynchronizationAdapter事務(wù)源碼解析
這篇文章主要介紹了spring的TransactionSynchronizationAdapter事務(wù)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
PrintStream和PrintWriter的區(qū)別簡介
這篇文章主要介紹了PrintStream和PrintWriter的區(qū)別簡介,具有一定借鑒價值,需要的朋友可以參考下2018-01-01

