• java arraylist的问题


    不得不说,我犯了错,很基础的。。

    遍历list的时候可以删除数组元素吗? 答案是:简单/增强for循环不可以,list.iterator()这样的方式就可以。

    我之前做过类似面试题的,不过忘记了, 不记得是list还是set或者map了 。list? 貌似也可以吧。

    对于set、map也是同理。

    如果是删除list倒数第一、倒数第二个元素,不会报错,

    private static void listtest() {
              List<String> list = new ArrayList<String>();  
              list.add("Java");  
              list.add("C");  
              list.add("C++");  
              list.add("C#");  
              try {
                  for(String str:list) {
                      System.out.println(str);
                      
                      if(str.equalsIgnoreCase("C++")) {
                          list.remove(str);
                      }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
              System.out.println(list);
        }

    打印:

    Java
    C
    C++    -----C#现在的索引为2,被认为已经遍历过了的,被略去!!
    [Java, C, C#]------ 删除是成功了的!!!

    把c++改成c,则报错

    Java
    C
    java.util.ConcurrentModificationException
    [Java, C++, C#]
        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
        at java.util.ArrayList$Itr.next(ArrayList.java:791)
        at Test.listtest(Test.java:154)
        at Test.main(Test.java:135)

    否则:

    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.huawei.oms.app.sysmgr.agent.neagent.db.DatabaseMonitor.queryDBInfo(DatabaseMonitor.java:291)
        at com.huawei.oms.app.sysmgr.agent.neagent.NeAgentImpl.queryDBInfo(NeAgentImpl.java:486)
        at sun.reflect.GeneratedMethodAccessor265.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.reflect.misc.Trampoline.invoke(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor114.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(Unknown Source)
        at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(Unknown Source)
        at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(Unknown Source)
        at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(Unknown Source)
        at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(Unknown Source)
        at com.sun.jmx.mbeanserver.PerInterface.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.MBeanSupport.invoke(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(Unknown Source)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(Unknown Source)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(Unknown Source)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(Unknown Source)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor176.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

    如何处理这种情况呢?

     用list的iterator就没问题, 这显然跟jdk、jvm本身相关。 —— 参考http://www.cnblogs.com/dongzhouzhou/articles/ConcurrentModificationException.html

    Iterator<String> iterator = list.iterator();
              while (iterator.hasNext()) {
                String str = (String) iterator.next();
                System.out.println(str);
                  if(str.equalsIgnoreCase("C")) {
                      iterator.remove();
                  }
                
              }

    同样的,对list做add操作会导致list长度动态增加、增加for和iterator都可以立即检测到。

    另外一方面,如果我们对list里面的元素做修改呢?—— 对基础类型元素不会生效,———— 而对引用类型会生效。 当然,估计没人这么用。

    private static void listtest() {
              List<Persion> list = new ArrayList<Persion>();  
              
              List<String> list2 = new ArrayList<String>(10); 
              Persion p1 = new Persion("lk1", 1);
              Persion p2 = new Persion("lk2", 2);
              Persion p3 = new Persion("lk3", 3);
              Persion p4 = new Persion("lk4", 4);
              list.add(p1);  
              list.add(p2);  
              list.add(p3);  
              list.add(p4);  
              
              Iterator<Persion> iterator = list.iterator();
              while (iterator.hasNext()) {
                  Persion str = (Persion) iterator.next();
                System.out.println(str.getName());
                  if(str.getName().equalsIgnoreCase("lk2")) {
                      str.setName("123123");
                      //iterator.remove();
                  }
              }
          
              System.out.println(list);
        }
        
    
    
    
    
    class Persion {
        String name;
        int age;
        public Persion(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        @Override
        public String toString() {
            
            return "name : " + this.name + "  age : " + this.age;
        }
    }
  • 相关阅读:
    工作一年感想
    launcher项目踩坑小结(1)
    滕王阁序
    PC端/移动端常见的兼容性问题总结
    Java中逻辑&和短路&&,逻辑|和短路||的区别
    Linux常用指令和系统管理命令总结
    Ajax学习笔记
    js放大镜特效
    《Python for Data Science》笔记之着手于数据
    Python2&3学习中遇到的坑
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/3670987.html
Copyright © 2020-2023  润新知