2022年11月9日 星期三

Java 關於 array 的處理

判斷是否為 Array

Object data = new int[]{};
System.out.println(data.getClass().isArray());  // true

取得 array 類型

可以用public Class<?> getComponentType() 這 method 來處理

如果是物件的 array,就會回傳物件的 class

Object data = new Number[]{};
System.out.println(data.getClass().getComponentType()); // class java.lang.Number

data = new String[]{};
System.out.println(data.getClass().getComponentType()); // class java.lang.String

如果是原始型別:

Object data = new char[]{};
System.out.println(data.getClass().getComponentType()); // char
System.out.println(data.getClass().getComponentType().isPrimitive()); // true

如果今天,該物件不是 array,getComponentType()會回傳null

Object data = "Lorem ipsum dolor sit amet.";
System.out.println(data.getClass().getComponentType()); // null

instanceof

Array 可以用 instanceof

Object data = new Double[]{};

// 是否為原始型別的 array
System.out.println(data instanceof double[]);  // false

// 是否為物件的 array
System.out.println(data instanceof Double[]);  // true
System.out.println(data instanceof Integer[]); // false
System.out.println(data instanceof Number[]);  // true
System.out.println(data instanceof Object[]);  // true

泛型

如果是 method ,可以用以下方式確保參數是 array

public static void main(String[] args) {
	foo(new Double[]{});
	foo(new Integer[]{});
	foo(new Float[]{});
}

static <T> void foo (T[] dataArray){
}

抑或是像下面這樣使用展開運算符

static <T> void foo (T ...dataArray){
}
限制參數類型

要限制參數類型的話:

static <T extends Number> void foo (T[] dataArray){
}

改成這樣的話,以下幾種寫法都沒問題:

foo(new Double[1]);
foo(new Integer[]{});
foo(new Float[]{});

但用 foo(new String[]{}); 的話就會報錯:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method foo(T...) is not applicable for the arguments (String[])


若我想限制參數得是數字字串,因為 Java 允許同名,參數卻不同的 method,所以可以這樣寫:

<T extends Number> void foo (T[] dataArray){
}
<T extends String> void foo (T[] dataArray){
}

Array to List

要將 array 轉成 List,如果是一般的物件,可以用 <T> List<T> java.util.Arrays.asList(T... a)

例如:

Double[] data = new Double[]{1.1, 3.3, 5.5};
Arrays.asList(data);

但這不適用於原始型別:

int[] data = new int[]{1, 2, 3};
System.out.println(Arrays.asList(data)); // [[I@762efe5d]

而原始型別的 array 又不能轉換成 Object[]

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Cannot cast from int[] to Object[]

Java 7 以下的話,只能手動轉換

int[] data = new int[]{1, 2, 3};
List<Integer> list = new ArrayList<Integer>();
for(int i: data){
	list.add(i);
}

System.out.println(list);

Java 8 有了 stream 後:

int[] data = new int[]{1, 2, 3};
List<Integer> list = Arrays.stream(data)
	.boxed()
	.collect(Collectors.toList());

System.out.println(list);

若你確定該 array 是哪種原始型別,可以直接用BaseStream處理,例如:

int[] data = new int[]{1, 2, 3};
List<Integer> list = IntStream.of(data)
	.boxed()   
	.collect(Collectors.toList());

System.out.println(list);


PS: 我在網上有看到有人將原始型別的 array 轉成物件 array 的方法(例如 double[]Double[]):

但這個要用 reflact ,而且很繁瑣,所以有興趣再自己看吧

參考資料

Crowder, T.J ., gnat, Spiewak, D. In Java, how do I dynamically determine the type of an array. Stack Overflow. https://stackoverflow.com/q/212805
mkyong, (2016, November 18). Java - How to convert a primitive Array to List. Mkyong.com. https://mkyong.com/java/java-how-to-convert-a-primitive-array-to-list/

沒有留言:

張貼留言