A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 Fozei 于 2016-5-5 09:05 编辑

关于集合里的toArray()方法,相信大家都不陌生:
[size=-1]Object[]
toArray()
          返回包含此 collection 中所有元素的数组。
[size=-1]
[size=-1]<T> T[]
toArray(T[] a)
          返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组

其中的第一个方法返回Object类型的数组。也就是说,不管你集合里原来存储的什么类型的元素,当你调用这个方法后,他会给你返回一个元素类型是Object的数组。如果你需要通过这个数组取出元素,并进行下一步操作,需要对从数组取出的元素,进行向下转型,也就是我们所说的类型强转。
我的疑问在第二个方法上:
他的返回类型是<T>,也就是我们说的泛型,而且需要传一个T类型的数组a当做参数!(槽点)当时我就想,如果我有一个List<String> list,调用toArray(T[] a)时,需要传一个String[] arr当做参数:
String[] arr = new String[list.size()];
arr = list.toArray(arr);
好,没问题,我们成功的得到了泛型能避免强转麻烦的效果。
看需求:
定义两个泛型集合List,要求调用同一个带泛型的自定义函数对这两个集合进行排序。
上代码:
  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.List;

  4. public class CollectionSort {

  5.         public static void main(String[] args) {
  6.                 List<String> list1 = new ArrayList<>();// 定义集合
  7.                 list1.add("b");
  8.                 list1.add("f");
  9.                 list1.add("e");
  10.                 list1.add("c");
  11.                 list1.add("a");
  12.                 list1.add("d");
  13.                 sort2(list1);// 调用方法
  14.                 System.out.println(list1); // a, b, c, d, e, f

  15.                 List<Integer> list2 = new ArrayList<>();// 定义集合
  16.                 list2.add(5);
  17.                 list2.add(8);
  18.                 list2.add(3);
  19.                 list2.add(1);
  20.                 list2.add(4);

  21.                 sort2(list2);// 调用方法
  22.                 System.out.println(list2); // 1,3,4,5,8
  23.         }

  24.         // 下面是不带泛型的toArray()方法
  25.         private static <T> void sort2(List<T> list) {// 将方法声明为泛型的,可以处理存储不同元素类型的集合
  26.                 // 如果用不带泛型的toArray方法,返回的是Object类型的数组,对数组类型进行强转
  27.                 T[] arr = (T[]) list.toArray();
  28.                
  29.                 // 对数组进行排序
  30.                 Arrays.sort(arr);
  31.                
  32.                 //对数组经行遍历,类型强转并存回集合
  33.                 for (int i = 0; i < arr.length; i++) {
  34.                         list.set(i, (T) arr[i]);
  35.                 }

  36.         }
  37. }
复制代码

以上代码是能实现功能的,但是,但是,但是在泛型方法里,有大量的类型强转。而泛型机制的出现不就是为了避免强转的麻烦吗???有没有高手想过用第二个方法,避免类型强转?我试过,是不行的……
第二个方法要往参数中传递一个数组作为参数,那我首先想到的是定义一个泛型数组:
T[] arr = new T[list.size()];
arr = list.toArray(arr);
貌似完美,可是人家压根就不让创建泛型数组……
那我怎么避免强转呢,我怎么在泛型函数中接收toArray()方法转换过来的数组呢?直接把第二个函数改成不用传数组做参数的该多么的简单美好,那样我们就可以这么用了:
T[] arr = list.toArray();
为毛非要传个数组做参数?在上面的例子里,我明显不知道我要往这个泛型函数里传的是存储有什么类型元素的集合,在你不让我创建泛型数组的情况下,你让我往里传一个啥类型的数组进去??泛型泛型,一是安全,二是避免强转,可是在这个案例里明显是自废武功,把避免强转的功能硬生生的给抹灭了,你说高司令是不是脑子抽抽了,这是明显的反人类呀……

写的很长,思路还很乱,不知道有人能看完不。

3 个回复

倒序浏览
顶贴防沉,大家帮忙看看,你是否也有这样的疑惑?
回复 使用道具 举报
顶贴是一种美德
回复 使用道具 举报
sunchuan 发表于 2016-5-5 21:29
顶贴是一种美德

哎,没人回,还是复制下来明天给老师看看。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马