Understanding of Java List toArray(new String[0]) & Detailed explanation of List's toArray() method

Understanding of Java List toArray(new String[0])

1、ArrayList的toArray

ArrayList provides a very convenient method toArray that converts a List into an array. toArray has two overloaded methods:

(1)list.toArray();

(2)list.toArray(T[] a);

Students who don't know the truth like to use the first one, which is written like this:

ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < 10; i++) {
    
    
    list.add(""+i);
}
 
String[] array= (String[]) list.toArray();

As soon as the result is run, an error is reported:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

The reason can be seen at a glance, Object[] cannot be converted into String[], the only way to convert is to take out each element and convert it. The mandatory type conversion in java is only for a single object. It is not possible to be lazy and convert the entire array into another type of array. This is similar to the need to initialize the array one by one . like this:

Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {
    
    
    String e = (String) arr[i];
    System.out.println(e);
}

So the first refactoring method is not so easy to use.

In fact, when converting a list to an array, the second reconstruction method is more convenient, and the usage is as follows:

String[] array =new String[list.size()];
list.toArray(array);
//实际项目中
List<String> sList = new ArrayList<String>();
for (MergeSoft mergeSoft : list) {
    
    
   if(mergeSoft.getCollectSoft() != null){
    
    
       sList.add(mergeSoft.getCollectSoft().getSid());
   }
}
String[] sids = sList.toArray(new String[sList.size()]);    
String[] devOnlyIds = collectSoftDao.queryDevOnlyIdBySid(sids);

2. Use set to duplicate data, and set to array

public String[] queryDevOnlyIdBySid(String[] sid) {
    
    
    String paramsStr = ArrayUtils.joinStringForSql(sid, "'", ",");//数组数据转为:'B07D26B8A919082612F9EFA55A9AACFC','3EF11C53F437A33A47C0B363B8D661BC'
    String sql = "SELECT di.devOnlyId FROM cems_device_installsoft di WHERE sId IN ( "+paramsStr+" )";
    
    List<Object> object = getSession().createSQLQuery(sql).list();
    Set<String> set = new HashSet<String>();
    for (int i = 0; i < object.size(); i++) {
    
    
        set.add(object.get(i).toString());//object里有重复的数据,采用set去除重复的数据
    }
    String[] devOnlyIds = new String[set.size()];    
    //Set-->数组    
    set.toArray(devOnlyIds); 
    return devOnlyIds;
}

Summarize:

1. The method of converting a set to an array, for example: list.toArray(new String[list.size()]) ;

2. Use set to remove duplicate data in the list

Set<String> set = new HashSet<String>();
for(int i=0; i < object.size(); i++){
    
    
    set.add(object.get(i).toString());
}

Then set is converted to an array:

set.toArray(new String[set.size()]);
List<String> roles = new ArrayList<>();
roles.toArray(new String[]{
    
    }))
return list.toArray(new String[0]);//这种方式效率最高
return list.toArray(new String[100]);//浪费了100个地址空间,以及申请空间的时间
return list.toArray(new String[500]);//浪费了500个地址空间,以及申请空间的时间
new String[0]就是起一个模板的作用


understand:

String[] s1 = list.toArray(new String[0]);

1. This method uses generics and is used in the creation of methods (equivalent to defining generics, T[] is using generic T)

Generics are a new feature of Java SE 1.5. The essence of generics is a parameterized type, which means that the type of data being manipulated is specified as a parameter. This parameter type can be used in the creation of classes, interfaces, and methods, and is called generic classes, generic interfaces, and generic methods, respectively.

2. This method returns an array of all elements in the collection; the runtime type of the returned array is the same as the runtime type of the specified array

3. Compared with toArray(), toArray returns an Object[] and then copies

toArray(new String[0]) is based on the type of the parameter array, and constructs an empty array of the corresponding type whose length is the same as the size of the ArrayList

img

When parameter.length <= list, list.toArray(parameter) creates an array with the same type as parameter and the same length as list, and assigns its reference to the array

img

When parameter.length > list, list.toArray(parameter) creates an array with the same type as parameter and a length of parameter.length, and assigns its reference to the array, and fills the part exceeding the length of the list with null

Therefore, when converting a collection to an array, the parameter specifies an empty array to save space, which can be written as: String[] s1 = list.toArray(new String[0]);


List's toArray() method

toArray() introduction

The toArray() method is a method provided in the List interface, which is used to convert the List object into an array object.
The toArray() method has two forms, the method without parameters and the method with generics, and an example is given next.

1.toArray()

	// toArray()源码
	public Object[] toArray() {
    
    
        return Arrays.copyOf(elementData, size);
    }

This method cannot specify the type of the conversion array, and the return value can only be an Object() array, so after getting the return value, type conversion is often required to convert Object[] to the type we need. However, there are often problems in the conversion part, as in the following example:

		List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Integer[] res = new Integer[list.size()];
        res = (Integer[])list.toArray();

The code can pass the syntax check, but a type conversion error will be reported at runtime, indicating that Object() cannot be simply converted to an array of other types.

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;

2.toArray(T[] a)

	// toArray(T[] a)源码
	public <T> T[] toArray(T[] a) {
    
    
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

This method is more flexible than the previous method without parameters, and requires the user to provide a generic type of the target object. After the array is converted, it will return an array of the specified type, and there is no type conversion error. Example of use:

		List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        String[] res = new String[list.size()];

In this way, the List object can be converted to String[].

Three ways to convert List to int[]

When introducing toArray() above, two methods are given, and the second method with generics is more widely used. I recently used the second method and found some problems. The function I want to achieve is as follows:

Given a List object: List list = new ArrayList<>();
Convert it to an int[] array.

I implement toArray() with a generic method, the code is as follows:

		List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        int[] res = new int[list.size()];
        res = list.toArray(res);

But in fact, the above code is wrong, because the generic parameter of toArray() cannot be int, it can only be its wrapper class Integer, so the List object cannot be directly converted into an array of general type through toArray(), the specific conversion There are three methods:

Method 1: Circular assignment

Take out the elements in the List one by one and assign them to the corresponding positions in the int[] array.

		List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        int[] res = new int[list.size()];
        for(int i = 0; i < list.size(); i++){
    
    
        	res[i] = list[i];
        }

Although this method requires traversal, the idea is simple and generally there is no error.

Method 2: Transformation through generics

Taking the final target array as int[] as an example, the conversion from List to int[] array can be realized with the help of Integer[] array, the code is as follows:

		List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Integer[] res = new Integer[list.size()];
        res = list.toArray(res);

In this way, an Integer[] array can be obtained, and then the Integer[] array can be converted into an int[] array using cyclic assignment.

Method 3: Use streams

Use the new methods provided in Java1.8 to achieve. The following are the mutual conversion codes of List, Integer[], int[], refer to "https://www.cnblogs.com/chcha1/p/10883068.html".

		int[] data = {
    
    4, 5, 3, 6, 2, 5, 1};        
        // int[] 转 List<Integer>       
        List<Integer> list1 = Arrays.stream(data).boxed().collect(Collectors.toList());       
        // Arrays.stream(arr) 可以替换成IntStream.of(arr)。      
        // 1.使用Arrays.stream将int[]转换成IntStream。       
        // 2.使用IntStream中的boxed()装箱。将IntStream转换成Stream<Integer>。       
        // 3.使用Stream的collect(),将Stream<T>转换成List<T>,因此正是List<Integer>。        
         
        // int[] 转 Integer[]       
        Integer[] integers1 = Arrays.stream(data).boxed().toArray(Integer[]::new);       
        // 前两步同上,此时是Stream<Integer>。      
        // 然后使用Stream的toArray,传入IntFunction<A[]> generator。       
        // 这样就可以返回Integer数组。      
        // 不然默认是Object[]。
         
        // List<Integer> 转 Integer[]       
        Integer[] integers2 = list1.toArray(new Integer[0]);       
         
        //  调用toArray。传入参数T[] a。这种用法是目前推荐的。      
        // List<String>转String[]也同理。        
         
        // List<Integer> 转 int[]       
        int[] arr1 = list1.stream().mapToInt(Integer::valueOf).toArray();       
         
        // 想要转换成int[]类型,就得先转成IntStream。      
        // 这里就通过mapToInt()把Stream<Integer>调用Integer::valueOf来转成IntStream         
        // 而IntStream中默认toArray()转成int[]。       
         
        // Integer[] 转 int[]       
        int[] arr2 = Arrays.stream(integers1).mapToInt(Integer::valueOf).toArray();      
         
        // 思路同上。先将Integer[]转成Stream<Integer>,再转成IntStream。       
        // Integer[] 转 List<Integer>       
        List<Integer> list2 = Arrays.asList(integers1);       
         
        // 最简单的方式。String[]转List<String>也同理。        
        // 同理       <br>         String[] strings1 = {"a", "b", "c"};      
         
        // String[] 转 List<String>       
        List<String> list3 = Arrays.asList(strings1);       
         
        // List<String> 转 String[]       
        String[] strings2 = list3.toArray(new String[0]);

Guess you like

Origin blog.csdn.net/qq_43842093/article/details/130043006