java arraylist的問題

不得不說,我犯了錯,很基礎的。。html

遍歷list的時候能夠刪除數組元素嗎? 答案是:簡單/加強for循環不能夠,list.iterator()這樣的方式就能夠。java

我以前作過相似面試題的,不過忘記了, 不記得是list仍是set或者map了 。list? 貌似也能夠吧。c++

對於set、map也是同理。面試

 

若是是刪除list倒數第1、倒數第二個元素,不會報錯,數組

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);
    }

 

打印:app

Java
C
C++    -----C#如今的索引爲2,被認爲已經遍歷過了的,被略去!!
[Java, C, C#]------ 刪除是成功了的!!!jvm

 

把c++改爲c,則報錯tcp

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)

 

 

不然:ide

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)

 

 

如何處理這種狀況呢?this

 用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;
    }
}
相關文章
相關標籤/搜索