2016-11-17 34 views
0

我已經嵌套在撰寫一本書的ArrayList:在Arraylists的ArrayList中,爲什麼所有對單個元素的操作都會影響所有其他索引?

private ArrayList<ArrayList<PageContents>> book = new ArrayList<>(); //A list of lists 
private ArrayList<PageContents> page = new ArrayList<>(); //A List of objects 

book.add(page); //Add new(first) page in book. 
PageContents pageContents = new PageContents(); //Create a new line 
pagecontents.setLine("This is a line on the page"); //Edit the line 
book.get(0).add(pagecontents); //Add the new (first) line to the first page of the book. 

因此,在實踐中,book.get(0).get(0).getLine();將返回的書的第一頁的第一行。

的問題

我最初以爲一切工作正常,因爲我開發的初始部分涉及得到一個單頁的權利,那麼我會擔心多頁。然後,當我將page列表附加到book ArrayList與book.new(page);我發現它與pagebook.get(0)完全一樣。 因此,book.get(0).get(0)的值與book.get(1).get(0)完全相同,或者book.get(0).get(20)book.get(1).get(20)完全相同。

然後我想:「沒什麼大不了的,它必須複製book.get(0)的數據,我只是在創建完成後立即清除page陣列列表book.get(1).clear();。」但是,這也清除了book.get(0)。然後我改變了數據book.get(1).get(9);,並且它也將book.get(0).get(9);更改爲相同的值。

現在我不知道發生了什麼。我認爲這可能與幾行內容有關,我將「書籍」數據與不同的類同步,可能是在複製指針,以便每個「頁面」指向相同的數據,但是在測試之後,我消除了作爲罪魁禍首。 (我剛剛刪除了這些方法)

我的ArrayLists是否在我的實現中有缺陷?
到目前爲止,ArrayList結構對我來說是完美的(直到我需要一個新的page,就是這樣)。我只需要每個新的page數組列表都是空白的,並將其添加到book列表中。

任何幫助表示讚賞。多謝你們!

更完整的示例:

代碼

private ArrayList<ArrayList<PageContents>> book = new ArrayList<>(); //A list of lists 
private ArrayList<PageContents> page = new ArrayList<>(); //A List of objects 

book.add(page); //Add new(first) page in book. 
PageContents pageContents1 = new PageContents(); //Create a new line 
pagecontents1.setLine("This is Line 1 on Page 1"); //Edit the line 
book.get(0).add(pagecontents1); //Add the new (first) line to the first page of the book. 

System.out.println("Page1 size: " + book.get(0).size() + "pages"); 
System.out.println("Page1: " + book.get(0).get(0).getLine()); 

System.out.println("Page2 size: " + book.get(1).size() + "pages"); 

if(book.get(1).isEmpty()) //Should book.get(1) should be empty 
{ 
    System.out.println("Page2: EMPTY"); 
} 
else 
{ 
    System.out.println("Page2: " + book.get(1).get(0).getLine()); 
} 

輸出(錯誤)

Page1 size: 1 
Page1: This is Line 1 on Page 1 
Page2 size: 1 
Page2: This is Line 1 on Page 1 

輸出(它應該是什麼,如果代碼藉機如預期d)

Page1 size: 1 
Page1: This is Line 1 on Page 1 
Page2 size: 0 
Page2: EMPTY 

如果我添加這些新代碼(爲了讓第2項內容)

PageContents pageContents2 = new PageContents(); //Create a new line 
pagecontents2.setLine("This is Line 1 on Page 2"); //Edit the line 
book.get(0).add(pagecontents1); //Add the new (first) line to the second page of the book. 

System.out.println("Page1 size: " + book.get(0).size() + "pages"); 
System.out.println("Page1: " + book.get(0).get(1).getLine()); 
System.out.println("Page2 size: " + book.get(1).size() + "pages"); 
System.out.println("Page2: " + book.get(1).get(1).getLine()); 

輸出(不正確的,這兩個頁面進行同樣的更改)

Page1 size: 2 
Page1: This is Line 1 on Page 1 
Page2 size: 2 
Page2: This is Line 1 on Page 1 
Page1 size: 2 
Page1: This is Line 1 on Page 2 
Page2 size: 2 
Page2: This is Line 1 on Page 2 

由於我添加了一個新行,兩個page列表都有2行。每個應只有一行不同的值。

+0

第一件事,你是等號需要在引文中:'=「pages」'應該是'+「= pages」'。或者將'='改成'+',這樣你只需要'+'頁面「' –

+0

是的,簡單的複製/粘貼錯誤。我修好了它。意思是把一個'+'連接起來。 – LazyBear

+0

確保在開始創建第二頁之前將'page'設置爲新的ArrayList;否則你只需將同一頁面添加到'book'兩次,並在第二次迭代中修改它。 – Gus

回答

2
import java.util.ArrayList; 

class PageContents 
{ 
    String Line; 

    public String getLine() 
    { 
     return Line; 
    } 

    public void setLine(String line) 
    { 
     Line = line; 
    } 

} 

public class MainClass 
{ 
    public static void main(String[] args) 
    { 
     ArrayList<ArrayList<PageContents>> book = new ArrayList<>(); 
     ArrayList<PageContents> page1 = new ArrayList<>(); 

     // Add new(first) page in book. 
     PageContents pageContents1 = new PageContents(); 
     pageContents1.setLine("This is Line 1 on Page 1"); 
     page1.add(pageContents1); 
     book.add(page1); 

     ArrayList<PageContents> page2 = new ArrayList<>(); 
     PageContents pageContents2 = new PageContents(); 
     pageContents2.setLine("This is Line 1 on Page 2"); 
     page2.add(pageContents2); 
     book.add(page2); 

     System.out.println("Page1 size: " + book.get(0).size() + "pages"); 
     System.out.println("Page1: " + book.get(0).get(0).getLine()); 

     System.out.println("Page2 size: " + book.get(1).size() + "pages"); 

     if (book.get(1).isEmpty()) 
     { 
      System.out.println("Page2: EMPTY"); 
     } else { 
      System.out.println("Page2: " + book.get(1).get(0).getLine()); 
     } 
    } 
} 
+0

這就是答案。正如少數人建議的那樣,我需要創建一個新的「頁面」列表,然後將其添加到「書籍」列表中。在Nani'2015的回答中,它是'ArrayList page2 = new ArrayList <>();'我實際上認爲我正在這樣做,但是我試圖解決這個問題的實際程序更具動態性,添加爲頁面1創建的第一個「頁面」。在我的實際程序中,新的「頁面」是在方法調用中創建的,所以我只是在那裏創建了'newPage'列表並將其添加到'book'列表中。現在,每個添加到「book」的newPage都是一個新實例。感謝大家。 – LazyBear

2

你確定你的演示程序是正確的嗎?

我試了下面的代碼,並得到了一個ArrayIndexOutOfBounds異常。你的代碼必須做的事情比你貼什麼更多...

Exception in thread "main" Page1 size: 1pages 
Page1: This is Line 1 on Page 1 
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 
    at java.util.ArrayList.rangeCheck(Unknown Source) 
    at java.util.ArrayList.get(Unknown Source) 
    at BookThingy.main(BookThingy.java:17) 

代碼...

import java.util.ArrayList; 

public class BookThingy { 

    public static void main(String[] args) { 
     ArrayList<ArrayList<PageContents>> book = new ArrayList<>(); //A list of lists 
     ArrayList<PageContents> page = new ArrayList<>(); //A List of objects 

     book.add(page); //Add new(first) page in book. 
     PageContents pageContents1 = new PageContents(); //Create a new line 
     pageContents1.setLine("This is Line 1 on Page 1"); //Edit the line 
     book.get(0).add(pageContents1); //Add the new (first) line to the first page of the book. 

     System.out.println("Page1 size: " + book.get(0).size() + "pages"); 
     System.out.println("Page1: " + book.get(0).get(0).getLine()); 

     System.out.println("Page2 size: " + book.get(1).size() + "pages"); 

     if(book.get(1).isEmpty()) //Should book.get(1) should be empty 
     { 
      System.out.println("Page2: EMPTY"); 
     } 
     else 
     { 
      System.out.println("Page2: " + book.get(1).get(0).getLine()); 
     } 
    } 

    public static class PageContents { 
     private String line; 

     public String getLine() { 
      return line; 
     } 

     public void setLine(String line) { 
      this.line = line; 
     } 
    } 
} 

安置自己的完整代碼(如果可能)或檢查其他方法不修改您的然後我會修改這個答案...

+0

對不起,無法發佈整個事情。它有大約1800行。我將代碼從一個更大的程序中分離出來以找出問題。我應該在發佈之前運行我發佈的示例。對於那個很抱歉。我會盡力清理它。問題是,如果上述概念是正確的,那麼我就沿着線路將其他東西擰緊了。一切都很好,直到我需要一個新的空白列表添加到書單。 – LazyBear

相關問題