注意!在subList生成子列表之后,一定不要随便更改原列表

举报
穆雄雄 发表于 2022/12/12 20:22:23 2022/12/12
【摘要】 大家好,我是雄雄。前几期我们说过,subList方法是返回原列表的子列表,并且我们还说过,在subList返回的子列表上操作时,会直接影响着原列表,原文在这里:subList?? subString???子列表只是原列表的一个视图那么,大家有没有想过这样一个问题,在调用subList方法返回子列表之后,我们要是不操作子列表,而是操作的原列表,会怎么样呢?下面我们先从一段代码上看起:publi...

大家好,我是雄雄。

前几期我们说过,subList方法是返回原列表的子列表,并且我们还说过,在subList返回的子列表上操作时,会直接影响着原列表,原文在这里:

subList?? subString???

子列表只是原列表的一个视图

那么,大家有没有想过这样一个问题,在调用subList方法返回子列表之后,我们要是不操作子列表,而是操作的原列表,会怎么样呢?

下面我们先从一段代码上看起:

public static void testSubList(){
    //初始化一个集合
    List<String> lists = new ArrayList<String>();
    //给集合中添加四个元素
    lists.add("A");
    lists.add("B");
    lists.add("C");
    lists.add("D");
    //遍历集合
    System.out.println("原来集合中的元素:");
    for (String str: lists) {
      System.out.print(str+" ");
    }
    System.out.println("\n子列表中的元素:");
    List<String>new_list = lists.subList(0, 2);
    
    for (String str: new_list) {
      System.out.print(str+" ");
    }
  }

运行结果如下:

​编辑

这块代码很好理解,无外乎就是初始化了个集合,并添加了几个元素,通过subList方法返回了一个子列表,最后将两个列表中的元素都遍历出来。

接下来我要改一下代码了,如下:

public static void testSubList(){
    //初始化一个集合
    List<String> lists = new ArrayList<String>();
    //给集合中添加四个元素
    lists.add("A");
    lists.add("B");
    lists.add("C");
    lists.add("D");
    //遍历集合
    System.out.println("原来集合中的元素:");
    for (String str: lists) {
      System.out.print(str+" ");
    }
    System.out.println("\n子列表中的元素:");
    List<String>new_list = lists.subList(0, 2);
    
    for (String str: new_list) {
      System.out.print(str+" ");
    }
    //给原来的集合中新加一个元素
    lists.add("E");
    System.out.println("\n新加元素之后原来集合的元素:");
    for (String str: lists) {
      System.out.print(str+" ");
    }
    
    System.out.println("\n新加元素之后子列表中的元素:");
    for (String str: new_list) {
      System.out.print(str+" ");
    }
  }

这段代码前面部分没有变,后面只是给原集合中新插入了一个元素“E” ,然后对原集合以及子列表进行遍历,运行结果如下所示:

​编辑

居然报错了?并且是在原集合中新加元素之后遍历子列表时报的错。ConcurrentModificationException是并发修改异常,但是我们这里并没有多线程操作,何来并发异常?其实,原因很简单,那就是subList方法是原列表的子列表,当原来的集合(原列表)修改之后,subList取出的子列表并未跟着一起修改,也就是不会生成新列表,最后在最字列表操作时,程序就会发现修改计数器(Modification)与预期的不符合,故抛出此异常。

因此,在subList生成子列表之后,一定不要随便更改原列表。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。