热爱技术,追求卓越
不断求索,精益求精

秒懂java,聊聊java类型、泛型、可变参数、集合与数组相互转换

java类型、泛型、可变参数

先说一个小问题,google的guava是一个不错的工具包,guava包内的Lists工具类的newArrayList像下面的这样使用为什么会报“Type mismatch: cannot convert from ArrayList<int[]> to List”的错误呢?

int array[] = {1, 2, 3, 4, 5};
List<Integer> list = Lists.newArrayList(array);

要回答这个问题,我们先来看看newArrayList的定义:

com.google.common.collect.Lists.newArrayList(E...)

newArrayList是一个参数数量可变的方法,其中E表示泛型,你像下面这样使用都是没有问题的:

//使用方法一
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
//使用方法二
int a = 1, b = 2, c = 3, d = 4, e = 5;
List<Integer> list = Lists.newArrayList(a, b, c, d, e);
//使用方法三
Integer array[] = {1, 2, 3, 4, 5};
List<Integer> list = Lists.newArrayList(array);

方法三和最开始报错的代码有什么区别呢?只是把int换成Integer就可以,用int就不行呢?

  1. 泛形要求能包容的是对象类型。
  2. 可变参数方法,编译器会把最后一个形参转化为一个数组形参。
  3. 可变参数是兼容数组类参数的。
  4. 基本类型在java里不属于对象,但数组(包括基本类型的数组)是对象。
  5. 基本类型都有其各自的包装类型,自动装箱和自动拆箱只针对基本类型。

上文的代码中,“使用方法一”和“使用方法二”会自动装箱,最后都能转化为Integer类型的数组形参;“使用方法三”中本身就是Integer类型的数组,可变参数是兼容数组类参数;对于最开始报错的那个代码,由于int类型的数组是一个对象,不能对对象进行自动装箱,可变参数方法Lists.newArrayList会把int类型的数组array当成一个参数看待,而不是数组的元素数量个参数。

集合与数组相互转换

数组和集合都是我们日常编码中经常用到的数据类型,如果给你一个集合,你会怎么样变成数组呢?给你一个数组,你会怎么把它变成集合呢?

方法一:遍历法

//数组变集合
int array[] = {1, 2, 3, 4, 5};
List<Integer> list = new ArrayList<Integer>(array.length);
for(int i = 0; i < array.length; i++){
    list.add(array[i]);
}

//集合变数组
List<Integer> list = initList();
Integer[] array = new Integer[list.size()];
for(int i = 0; i < list.size(); i++){
    array[i] = list.get(i);
}

方法二:使用第三方工具类或JDK自带工具类

//集合转数组
Collection<Integer> collection = initCollection();
Integer[] array = collection.toArray(new Integer[collection.size()]);

//数组转集合,利用guava的Lists,Sets等工具类
com.google.common.collect.Lists.newArrayList(E...)
org.assertj.core.util.Sets.newLinkedHashSet(T...)
org.assertj.core.util.Sets.newTreeSet(T...)

常用方法二,方法一不用。

赞(1)
未经允许不得转载:LoveCTO » 秒懂java,聊聊java类型、泛型、可变参数、集合与数组相互转换

热爱技术 追求卓越 精益求精