List和数组使用过程中的常见的坑

1.从整型值List中删除等于某个值的元素,应当先转型

删除指定索引的元素int remove(int index)和删除某个元素int remove(Object e)都可以用于从List中删除指定的元素。
对于整型值List,如果我们想要从中删除掉某个值:

// 删除掉entry中值等于target的元素
LinkedList<Integer> entry = new LinekdList<>();
entry.add(1);
entry.add(10);
entry.add(100);
int target = 100;
entry.remove(target);

将会报错IndexOutOfBounds,因为java仅当没有可以在没有强制/自动装箱的情况下调用的方法时,才会执行自动装箱和隐式向上转换。在上面的代码中优先调用的是remove(int index)方法,而entry中没有index等于100的元素。
如果想要从该List中删除值等于target的元素,正确的做法应该为:

entry.remove((Integer)target);

entry.remove(Integer.valueOf(target));

2.创建泛型数组不能直接用new操作符

在创建ArrayList的数组时,使用

public static ArrayList<myObject>[] a = new ArrayList<myObject>[2];

会报错 Generic array creation。Java不支持直接用new操作符创建带泛型的数组,必须强制转型,例如:

@SuppressWarnings("unchecked")
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2];

(更多内容请参考:
https://stackoverflow.com/questions/7131652/generic-array-creation-error/23034391
https://www.liaoxuefeng.com/wiki/1252599548343744/1265105940850016)

3.List和数组之间的相互转换

3.1 List转换为数组最好不要直接用toArray方法

通过for循环遍历将List转换为数组,可以将list的元素依次加入数组中;但是这样的话,代码会很长,使用List的toArray()方法似乎是更明智的选择:

List<String> stringList = new ArrayList<>(){{add("a"); add("b"); add("c");}};
String[] strings = (String[]) stringList.toArray();

然而,这样会直接报java.lang.ClassCastException。这是因为直接调用toArray()方法返回的是Object[],而Object[]是无法直接向下转型为String[]的。
更合适的方法应该是使用List的toArray(T[])方法:

String[] strings = stringList.toArray(new String[stringList.size()]);

这种写法可以进一步简化为List接口定义的T[] toArray(IntFunction<T[]> generator)方法:

String[] strings = stringList.toArray(String[]::new);

然而,峰回路转,这个办法依然埋着一个深不见底的坑。如果我们对于int[]和Integer列表进行转换的话:

List<Integer> numList = new ArrayList<>(){{add(1); add(2); add(3);}}
int[] nums = (int[]) numList.toArray(new int[numList.size()]);

很可惜,还是会报错,因为toArray(T[])中的泛型类型int与List的泛型类型Integer不匹配。只能写成如下的格式:

Integer[] nums = (Integer[]) numList.toArray(new Integer[numList.size()]);

那如果一定要求转换为int[]而不是Integer[]该怎么办呢?聪明的同学们可能会想到:

int[] nums = numList.stream().mapToInt(Integer::intValue).toArray();

这种写法倒确实可以行得通。可惜的是执行这一行代码的耗时远远超过了通过for循环将List转化为数组的时间。看来将List转化为int数组,只能老老实实通过for循环实现了。

3.2 数组转换为List最好不要直接用asList方法

同样,可以使用for循环,但是有没有更简洁的办法呢?不难想到Arrays类的asList()方法或者List的ofList方法:

List<String> stringList1 = strings.asList();
List<String> stringList2 = List.ofList(strings);

然而,用上面两个方法返回的List对象都是只读List,只读List调用add()、remove()方法会抛出UnsupportedOperationException。
因此,推荐使用以下方法:

ArrayList<String> stringList3 = new ArrayList<String>(Arrays.asList(strings));

或者:

List<String> stringList4 = new ArrayList<String>(strings.length);
Collections.addAll(stringList4, strings);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值