Java-ArrayList使用注意

70 篇文章 0 订阅
50 篇文章 0 订阅

Java-ArrayList使用注意

  1. 使用Arrays.asList的注意事项

使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方
法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适
配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { “yang”, “hao” };
List list = Arrays.asList(str);
第一种情况:list.add(“yangguanbao”); 运行时异常。
第二种情况:str[0] = “changed”; 也会随之修改,反之亦然。

使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

往列表里面新增数据

String[] str = new String[] { "apple", "grapes" };
List list = Arrays.asList(str);
System.out.println(list);
list.add("banana");

结果

[apple, grapes]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at LearnArrayList.main(LearnArrayList.java:22)

Process finished with exit code 1

更改原数组的值

String[] str = new String[]{"apple", "grapes"};
List list = Arrays.asList(str);
System.out.println(list);
str[0] = "banana";
System.out.println(list);

结果

[apple, grapes]
[banana, grapes]

原因

Arrays.asList返回的并不是我们常用的ArrayList,而是Arrays类的内部类AbstractList类,重写了很多方法,比如我们上面使用的contains方法,但是却没有重写add方法,所以我们在调用add方法时才会抛出java.lang.UnsupportedOperationException异常。

  1. ArrayList的subList

subList用于返回原集合的子集

示例

List<String> carList = new ArrayList<>();
carList.add("奥迪");
carList.add("宝马");
carList.add("奔驰");
carList.add("保时捷");
carList.add("马萨拉蒂");
System.out.println(carList);

List<String> myCarList=carList.subList(2,3);
System.out.println(myCarList);
List<String> otherCarList=carList.subList(3,3);
System.out.println(otherCarList);
[奥迪, 宝马, 奔驰, 保时捷, 马萨拉蒂]
[奔驰]
[]

注意,subList的定义如下
List subList(int fromIndex, int toIndex);
fromIndex, inclusive, and toIndex, exclusive. (IffromIndex and toIndex are equal, the returned list isempty.)

subList(a,b) 返回的是包含a但是不包含b的子集,如果a=b,则返回空集

子集使用
  • 修改原集合元素的值,会影响子集合

    示例

    List<String> carList = new ArrayList<>();
    carList.add("奥迪");
    carList.add("宝马");
    carList.add("奔驰");
    carList.add("保时捷");
    carList.add("马萨拉蒂");
    System.out.println(carList);
    
    List<String> myCarList=carList.subList(2,3);
    System.out.println(myCarList);
    carList.set(2,"五菱");
    System.out.println(myCarList);
    

    结果

    [奥迪, 宝马, 奔驰, 保时捷, 马萨拉蒂]
    [奔驰]
    [五菱]
    
  • 修改原集合的结构,会引起ConcurrentModificationException异常

    【强制】在 subList 场景中,高度注意对原集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生 ConcurrentModificationException 异常。

    示例

      List<String> carList = new ArrayList<>();
      carList.add("奥迪");
      carList.add("宝马");
      carList.add("奔驰");
      carList.add("保时捷");
      carList.add("马萨拉蒂");
      System.out.println(carList);
      
      List<String> myCarList=carList.subList(2,3);
      System.out.println(myCarList);
      
      carList.add("别克");
      System.out.println(myCarList);//修改结构后导致遍历异常
    

    结果

      [奥迪, 宝马, 奔驰, 保时捷, 马萨拉蒂]
      [奔驰]
      Exception in thread "main" java.util.ConcurrentModificationException
      	at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1239)
      	at java.util.ArrayList$SubList.listIterator(ArrayList.java:1099)
      	at java.util.AbstractList.listIterator(AbstractList.java:299)
      	at java.util.ArrayList$SubList.iterator(ArrayList.java:1095)
      	at java.util.AbstractCollection.toString(AbstractCollection.java:454)
      	at java.lang.String.valueOf(String.java:2994)
      	at java.io.PrintStream.println(PrintStream.java:821)
      	at LearnArrayList.main(LearnArrayList.java:52)
      
    
  • 修改子集合元素的值,会影响原集合

    示例

    List<String> carList = new ArrayList<>();
    carList.add("奥迪");
    carList.add("宝马");
    carList.add("奔驰");
    carList.add("保时捷");
    carList.add("马萨拉蒂");
    System.out.println(carList);
    
    List<String> myCarList=carList.subList(2,3);
    System.out.println(myCarList);
    
    myCarList.set(0,"长安");
    System.out.println(carList);
    

    结果

    [奥迪, 宝马, 奔驰, 保时捷, 马萨拉蒂]
    [奔驰]
    [奥迪, 宝马, 长安, 保时捷, 马萨拉蒂]
    
  • 修改子集合的结构,会影响原集合

    注意这里的顺序是往子集结尾的地方插入

    示例

    List<String> carList = new ArrayList<>();
    carList.add("奥迪");
    carList.add("宝马");
    carList.add("奔驰");
    carList.add("保时捷");
    carList.add("马萨拉蒂");
    System.out.println(carList);
    
    List<String> myCarList=carList.subList(2,3);
    System.out.println(myCarList);
    
    myCarList.add("比亚迪");
    System.out.println(carList);
    

    结果

    [奥迪, 宝马, 奔驰, 保时捷, 马萨拉蒂]
    [奔驰]
    [奥迪, 宝马, 奔驰, 比亚迪, 保时捷, 马萨拉蒂]
    
总结

ArrayList的subList方法,返回的是原集合的一个子集合(视图),非结构性修改任意一个集合的元素的值,都会彼此影响,结构性修改原集合时,会报ConcurrentModificationException异常,结构性修改子集合时,会影响原集合,所以使用时要注意,避免程序错误或者异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值