First, let's popularize science to unfamiliar brothers:
Array. The aslist () method is used to convert an array to a collection
For friends who often do data processing
It should be no stranger
But then again
This method has several hidden "pits"
A fraternity may be recruited
Let's find out next
It's said that the sharing effect is better!!
Pit 1: arrays of basic data types cannot be directly converted
Error case:
//Defines an array of int classes of the basic data type int[] arr = {1, 2, 3}; //Using array The aslist () method is converted to a collection List list = Arrays.asList(arr); //Output the converted set information log.info("list:{} size:{}", list, list.size());
Expected output:
list:[1, 2, 3] size:3
Console actual output:
list:[[I@1c53fd30] size:1
Obviously, the hidden "pit" appeared,
An array with three elements has only one element after conversion, and there is a problem with the data type.
Cause analysis:
Although int can be boxed into wrapper class integer, int array cannot be boxed into integer array as a whole.
Pit removal scheme:
1. Arrays. Net is provided above Java 8 Stream method cast
int[] arr1 = {1, 2, 3}; List list1 = Arrays.stream(arr1).boxed().collect(Collectors.toList()); log.info("list:{} size:{}", list1, list1.size());
2. Define arrays directly using the wrapper class integer
Integer[] arr2 = {1, 2, 3}; List list2 = Arrays.asList(arr2); log.info("list:{} size:{}", list2, list2.size());
Modified console output:
list:[1, 2, 3] size:3
We got the result we expected, and we succeeded in getting rid of the first pit!
Brother, don't be stingy with your praise! It is the power that I continue to output, and we continue to get out of the pit:
Pit 2: the converted set cannot add or delete elements
Error case:
//This time we use the reference class String array String[] arr = {"1", "2", "3"}; List list = new ArrayList(Arrays.asList(arr)); try { //Try to append an element to the converted list list.add("5"); } catch (Exception ex) { ex.printStackTrace(); } //After conversion, modify the value of the original array arr[1] = "4"; //Output original array and converted set log.info("arr:{} list:{}", Arrays.toString(arr), list);
Expected output:
arr:[1, 4, 3] list:[1, 2, 3, 5]
Console actual output:
//The first is the exception of the list append element java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148) at java.util.AbstractList.add(AbstractList.java:108) at org.geekbang.time.commonmistakes.collection.aslist.AsListApplication.wrong2(AsListApplication.java:41) at org.geekbang.time.commonmistakes.collection.aslist.AsListApplication.main(AsListApplication.java:15) //Element output arr:[1, 4, 3] list:[1, 4, 3]
According to the console output,
Not only did we fail to append elements to the list,
Our modifications to the elements in the original array also affect the set list,
This is the third pit:
Pit 3: the modification of the original array will affect the List after conversion
Cause analysis:
Actually, Arrays The List returned by the aslist method is not the Java util. ArrayList, but the internal class ArrayList of Arrays.
The difference between the two is that the ArrayList inner class inherits from the AbstractList class and does not override the add method of the parent class, so the above exception is generated.
As for the third pit, because ArrayList directly uses the original array, it will have the effect of sharing arrays with each other.
If we pass through arrays The List obtained by aslist is handled by other methods. It is easy to modify each other because the array is shared, resulting in implicit "bug s".
It is difficult to find the cause of this problem, so we should be very careful.
Pit removal scheme:
The method is not hard to guess,
We just need to use a real Java util. ArrayList to store the converted list
String[] arr = {"1", "2", "3"}; //Use Java util. ArrayList receives the converted list List list = new ArrayList(Arrays.asList(arr)); arr[1] = "4"; try { list.add("5"); } catch (Exception ex) { ex.printStackTrace(); } log.info("arr:{} list:{}", Arrays.toString(arr), list);
Modified console output:
arr:[1, 4, 3] list:[1, 2, 3, 5]
The output meets our expectations.
Our new ArrayList can not only do the add operation, but also separate from the previous array.
This is a good solution to the problem!
end