簡體   English   中英

與迭代器的ConcurrentModificationException

[英]ConcurrentModificationException with Iterators

我一直在編寫一個程序,我遇到了一些我能夠正確解決的問題。 但是,我的程序拋出一個ConcurrentModificationException ,我不知道我能做什么。

我正在使用NetBeans 8.0.2編寫代碼來創建Java桌面應用程序(根據我的教授的要求)。 該計划的目的是管理一家酒店。 因此,它有一些部分,如“客戶”,“員工”和“預訂”(給我帶來問題的那個)。

在每個部分,我都有一個使用DefaultTableModelJTable 在每個部分中,我都在使用硬盤驅動器上的文件來使更改持久化。 我編寫了新的客戶/員工課程。 現在,我正在嘗試編碼預訂和取消預訂方法。 在我進入“unbooking”部分之前,一切都很順利。

在表和模型之后我有一個ArrayList 在這個特定的部分,我有三個:

  • 整個桌子一個
  • 一個只包含免費房間
  • 一個只有已預訂的房間。

預訂部分很好,我能夠修改表,文件和ArrayList沒有任何錯誤,我的程序實際上做了應有的事情。 但我無法讓unbooking部分工作。 它基本上應該與預訂相反。

我將發布我的一小部分代碼,但如果您需要了解其他任何內容或需要我的代碼的更多部分,我很樂意分享它。

我的代碼:

public class GestionInstalaciones extends javax.swing.JFrame {
    private final String ruta = System.getProperties().getProperty("user.dir");
    private final File archivo = new File (ruta+"\\Instalaciones.txt");
    private final DefaultTableModel modelo = new DefaultTableModel();
    private final ArrayList contenidoInstalaciones;
    private final ArrayList contenidoInstalacionesOcupadas;
    private final ArrayList contenidoInstalacionesLibres;
    public GestionInstalaciones() {
       initComponents ();
       contenidoInstalaciones = new ArrayList();
       contenidoInstalacionesOcupadas = new ArrayList();
       contenidoInstalacionesLibres = new ArrayList();
       //Añadimos las columnas a la tabla.
       modelo.addColumn ("Tipo");
       modelo.addColumn ("Nombre Instalacion");
       modelo.addColumn ("NIF del Ocupante");
       cargarTabla();
}

private void cargarTabla(){
    this.contenidoInstalaciones.clear();
    FileReader fr = null;
    BufferedReader br;
    String tipo;
    String nombre;
    String NIFocupante;
    String[] partes;
    String linea;

    try{
        fr = new FileReader(archivo);
        br = new BufferedReader(fr);

        while ((linea=br.readLine())!=null) {
            //Adding info to general ArrayList
            this.contenidoInstalaciones.add(linea);
            //Splitting line into 3 components.
            partes = linea.split(",",3);
            tipo = partes[0];
            nombre = partes[1];
            NIFocupante = partes[2];

            //Skipping header.
            if ( tipo.equals( "Tipo" )) { continue; }

            //Añadimos la fila al modelo.
            modelo.addRow(partes);
        }
        TablaInstalaciones.setModel(modelo);
    }
    //Capturamos excepciones y cerramos fichero.
    catch(IOException e) {}
    finally { try { if ( null != fr ) { fr.close(); } } catch (IOException e2){ } }
}//end cargarTabla()

private void botonLiberarInstalacionActionPerformed(java.awt.event.ActionEvent evt) {                                                        
    Object linea;
    int contador=0;
    String aux; 
    String tiposATrabajar = "";
    String[] tiposAInsertar;
    Iterator instalacionesOcupadas;

    //Cleaning of already booked ArrayList.
    //this.contenidoInstalacionesOcupadas.clear();

    instalacionesOcupadas = contenidoInstalacionesOcupadas.iterator();
    this.comboTipoALiberar.removeAllItems();
    this.comboTipoALiberar.addItem("Seleccione");

    //Reading the general Table.
    for (int z = 0; z < TablaInstalaciones.getRowCount() ; z++) {
        //The booking parameter is on the 3rd place.
        if(!TablaInstalaciones.getValueAt(z,2).equals("")){
            //Putting the line into the ArrayList for booked rooms..
            linea = TablaInstalaciones.getValueAt(z,0) + "," + TablaInstalaciones.getValueAt(z,1) + "," + TablaInstalaciones.getValueAt(z,2);
            this.contenidoInstalacionesOcupadas.add(linea);
            contador++;
        }
    }

    **//Reading the booked ArrayList to put the right values on the combobox related. 
      //===> THIS LINE IS GIVING THE ERROR !!!
    while(instalacionesOcupadas.hasNext()) {** 
        aux = instalacionesOcupadas.next().toString().split(",",3)[0];
        //Checking to add only 1 kind of each room type.
        if(!tiposATrabajar.contains(aux)); {
            if (tiposATrabajar.equals("")) { tiposATrabajar=aux; }
            else { tiposATrabajar = tiposATrabajar + "," + aux; }
        }
    }      
    //
    tiposAInsertar = tiposATrabajar.split(",");
    //Adding the type into the combobox.
    for (String elemento: tiposAInsertar){ this.comboTipoALiberar.addItem(elemento.replace(",","")); }

}   

當您正在循環遍歷所述鏈時,對元素鏈(列表)進行更改時會發生ConcurrentModificationException

我經常遇到它並且總是通過反向循環遍歷列表來解決它,這樣你就可以向后循環,如果你想要的話你可以改變或刪除元素而不會搞亂你循環的鏈(列表)。

我會為你提供代碼,但我覺得很難讀你的代碼,所以現在必須這樣做。

希望這有幫助,祝你好運!

如果自上次使用迭代器以來,您正在迭代的Collection的內容已經更改,那么如果您嘗試使用或重用它,則會出現異常。 創建一個新的 - 作為一般規則, 不要重用迭代器

你是:

  1. 創建一個迭代器
  2. 修改列表
  3. 列表修改后使用迭代器←錯誤!

您應該在創建迭代器之前修改列表。

此外,您應該嘗試最小化局部變量的范圍

相反:

Iterator<String> someIterator = strings.iterator();
while (someIterator.hasNext()) {
    doSomething();
}

你應該這樣做:

for (Iterator<String> iter = strings.iterator(); iter.hasNext();) {
    doSomething();
}

當然,如果您(如您所說) 不需要修改列表,請使用for-each循環:

for (String s : strings) {
    doSomething();
}

一些不相​​關的觀點:

  • 為什么要編寫extends java.awt.JFrame類的東西? 導入它並改為使用JFrame
  • 在需要時聲明並初始化變量。 如果你for循環前初始化了Iterator ,你就不會遇到這個問題。
  • 使用泛型 非泛型Collection只會在運行時出錯,而泛型Collection則會產生編譯錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM