2015-03-24 62 views
2

所以我試圖創建一個功能,其中可以保存兩個當前對象,以便下次可以加載它們而不是再次創建。我有以下課程的問題:數組列表找不到對象

public class Investor implements Serializable { 

     private String investorName; 
     private double investorCapital; 
     private ArrayList<Share> shareOwned; 
     private ArrayList<Integer> numberOwned; 

     public Investor(String name, double capital) { 
      investorName = name; 
      investorCapital = capital; 
      shareOwned = new ArrayList<Share>(); 
      numberOwned = new ArrayList<Integer>(); 
     } 

P.S.我刪除功能只是爲了顯示結構。然後,我執行下面的代碼:

File investorData = new File("inv1.ser"); 

if(investorData.exists()) { 
      try { 
       FileInputStream loadData = new FileInputStream(investorData); 
       ObjectInputStream ois = new ObjectInputStream(loadData); 
       inv1 = (Investor) ois.readObject(); 
       loadData.close(); 
       ois.close(); 
      } catch (Exception exc) { 
       JOptionPane.showMessageDialog(null, "An error occurred", "Error", JOptionPane.ERROR_MESSAGE); 
      } 
     } 
     else { 
      try { 
       String name = JOptionPane.showInputDialog(null, "What is your name?", "Creating new investor", JOptionPane.QUESTION_MESSAGE); 
       double capital = Double.parseDouble(JOptionPane.showInputDialog(null, "What is your investor capital?", "Creating new investor", JOptionPane.QUESTION_MESSAGE)); 
       inv1 = new Investor(name, capital); 
      } 
      catch(NullPointerException exc) { 
       JOptionPane.showMessageDialog(null, "You must enter details in order to proceed", "File Not Found", JOptionPane.ERROR_MESSAGE); 
      } 
      JOptionPane.showMessageDialog(null, "New investor " + inv1.getInvestorName() + " with balance: " + inv1.getInvestorCapital() + " has been successfully created!", "Investor Created", JOptionPane.INFORMATION_MESSAGE); 
      try { 
       FileOutputStream saveFile = new FileOutputStream(investorData); 
       ObjectOutputStream oos = new ObjectOutputStream(saveFile); 
       oos.writeObject(inv1); 
       saveFile.close(); 
       oos.close(); 
      } 
      catch(Exception exc) { 
       JOptionPane.showMessageDialog(null, "An error occurred", "Error", JOptionPane.ERROR_MESSAGE); 
      } 
     } 

當我啓動程序第一次提示我創造它做成功,並在合適的位置等保存新的投資對象。之後,我可以使用程序:買/賣股票等,但一旦我關閉它,並再次打開,它不承認之前購買的股票。因此,例如,如果我關閉了Gold-100,那麼當我再次打開程序時,它將顯示Gold-100,並且將嘗試再購買10個,它會添加新的Gold對象來分享,並且我將擁有Gold - 100,Gold - 10.據我瞭解,它不能識別舊的Gold對象並添加新的對象(如果它從未存在,那麼它是有意的)。

我不能上傳整個程序,因爲它是相當大的,有buyShare方法在投資類:

public void buyShare(double price, int amount, Share stock) { 
     investorCapital -= price * amount; 
     if(shareOwned.contains(stock)) { 
      numberOwned.add(shareOwned.indexOf(stock), numberOwned.get(shareOwned.indexOf(stock)) + amount); 
     } 
     else { 
      shareOwned.add(stock); 
      numberOwned.add(amount); 
     } 
    } 

分享類(無功能):

public class Share implements Serializable { 

    private String shareName; 
    private double shareValue; 
    private int shareAvailable; 
    private final double SHARE_PURE_VALUE; 

    public Share(String name, double value, int available) { 
     shareName = name; 
     SHARE_PURE_VALUE = value; 
     shareValue = value/available; 
     shareValue = Math.round(shareValue * 10)/10; 
     shareAvailable = available; 
    } 

你可以看到我的檢查「包含」它應該返回只是添加numberOwned,但它會創建一個新的,所以它找不到之前保存的以前的黃金。對不起,如此糟糕的解釋,我可以發送一個程序,如果這會更方便。

+0

不發佈所有,只是做一個最小的重現器。它很可能會讓你自己找到錯誤。 – eckes 2015-03-24 22:00:18

回答

0

如果我理解你的問題,你希望有「金-110」,而不是「金-100,金-10」,對嗎?

所以,我認爲你必須在Share類上實現equals和hashCode方法。當「shareOwned.contains(stock)」被調用時,永遠不會返回true,對嗎?

這就是爲什麼你總是在列表中有一個新的股票對象。

添加commons-lang3到項目,並把這段代碼在你的分享類:

@Override 
public boolean equals(Object obj) { 
    return EqualsBuilder.reflectionEquals(this, obj); 
} 

@Override 
public int hashCode() { 
    return HashCodeBuilder.reflectionHashCode(this); 
} 

應該工作。

+0

是的,這是正確的!它進行到其他,這是爲什麼時分享不存在 – AlenEviLL 2015-03-24 22:05:56

+0

我改變了我的答案上面添加一個可能的解決方案爲您的問題。 – dansouza 2015-03-24 22:36:16

+1

您不必爲'ArrayList'實現'hashCode()'。 – EJP 2015-03-24 23:04:02

-1

非常感謝!我解決了這個問題。正如前面提到的,我必須在Share類中重寫equals()和hashCode()方法,現在所有的東西都可以完美工作(至少似乎)。我試圖使用循環來檢查名稱,但這種解決方案要簡單得多!

@Override 

    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Share share = (Share) o; 

     if (!shareName.equals(share.shareName)) return false; 

     return true; 
    } 

    @Override 
     public int hashCode() { 
      return 1; 
     } 

     public void setMarketValue() { 
      shareValue = SHARE_PURE_VALUE/shareAvailable; 
      shareValue = Math.round(shareValue * 10)/10; 
     } 
+1

您沒有解決問題。 @dansouza解決了這個問題。沒有必要重申他的答案。你不必爲'ArrayList'實現'hashCode()'。 – EJP 2015-03-24 23:04:11

+0

是的,我感謝他,但我只是使用shareName變量而不是使用EqualsBuilder你甚至看過我們的答案? @EJP – AlenEviLL 2015-03-24 23:11:03

+0

的確如此。 :) – dansouza 2015-03-24 23:16:56

相關問題