ArrayList 里的 toArray() 和 toArray(T[] a) 的不同作用【jdk源码分析】

官方解释:

    (1)toArray() :按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

    (2)toArray(T[] a): 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。

乍眼一看,感觉都差不多,其实说的很清楚,简单的解释就是,toArray()转成Object[];而toArray(T[] a)转成指定类型的数组。

例:以下代码关于User 对象,就不列出来了。很简单,当做一个对象就可以了。

(1)toArray()

	List<User> list = new ArrayList<>(); 
	for (int i = 0; i < 10; i++) {
		User user = new User();
		user.setName("张三"+i);
		user.setAge(i+"");
		list.add(user);
	}
	Object[] array = list.toArray();
    	
	for (int i = 0; i < array.length; i++) {
		User user1 = (User)array[i];
		String age = user1.getAge();
		System.out.println(age);
		System.out.println((User)array[i]);
	}

  注意:使用toArray()转数组,转成的是Object[],可以在使用的时候在强制转换成想要的类型

  有的小伙伴儿可能说直接把数组强制转换不就可以了吗,像这样:

                       User[] array = (User[])list.toArray();
                       for (int i = 0; i < array.length; i++) {
                              System.out.println(array[i]);
                        }

  这样是会报错的 【 java.lang.ClassCastException】:类型转换错误。

  这里有句话比较重要:java中的强制类型转换只是针对单个对象的。

(2)toArray(T[] a):  转换成指定的类型的数组,在使用时就可以不用再强制转换了

	List<User> list = new ArrayList<>(); 
	for (int i = 0; i < 10; i++) {
		User user = new User();
		user.setName("张三"+i);
		user.setAge(i+"");
		list.add(user);
	}
	User[] array = new User[list.size()];
	list.toArray(array);
	for (int i = 0; i < array.length; i++) {
		System.out.println(array[i]);
	}

 

扩展部分

在阅读jdk源码时,阅读到 toArray(T[] a) 方法时,感觉有些代码让我产生了思考。接下来一起看看

    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

疑惑点:

(1)、在这个方法里我觉得

                 if (a.length > size)
                        a[size] = null;

            这两行代码可以不要。为啥不要呢:转换数组时,大于原数组长度时,原数组长度后的数据默认就为空

           你可以这样测试:

                            User[] array = new User[15];
                                  for (int i = 0; i < 10; i++) {
                                       User user = new User();
                                       user.setName("张三"+i);
                                       array[i]=user;
                                   }
                            for (int i = 0; i < array.length; i++) {
                                  System.out.println(array[i]);
                            }

           这样相当于手动模拟转换,结果 array.length>10 以后的值默认为null

(2)、第四行代码,跟进 copyOf() 方法,如下

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

  在方法里有句代码:

           System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));

 我觉得  original.length 等于 newLength  所以,感觉 Math.min(original.length, newLength)) 这个方法没啥作用。因为 original.length就等于原数组长度;newLength就等于原list的size()

结束语:关于疑点,只是针对list转数组方法而言。当然了我分析的不一定正确,如果各位有其它看法,欢迎评论。若各位觉得我分析的不正确,也希望各位帮我指出来,谢谢了~~~

猜你喜欢

转载自blog.csdn.net/weixin_40841731/article/details/85257129