一)背景
主要是為了實現(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)源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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)換測試類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
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ū)別
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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ā)手冊》學習整理。希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/p812438109/article/details/81190087