![](/img/trans.png)
[英]Unexpected behavior of Java ArrayList.set() method with multiplication in forEach loop
[英]Explanation for different behavior in Vector.set() and ArrayList.set()
除了項目背景,我已經實現了一個自定義JComboBoxes的表。 ComboBoxes的每一行都是獨占的:雖然每個ComboBox都有自己的模型(允許不同的選擇),但每行只能選擇一次。 這是通過在選擇時在項目的前面添加標記並在取消選擇時再次刪除它來完成的。 如果用戶嘗試選擇標記的項目,則不會發生任何事情。
但是,這僅在使用Vector作為選項列表的后盾時才有效。 我可以得到字符串的Vector,使用set()或setElementAt(),並且它可以運行。
但是,使用ArrayList而不是Vector,這根本不起作用。 我的印象是ArrayLists的功能類似,因為我可以檢索匿名ArrayList,更改其內容,並且依賴於該ArrayList內容的所有其他對象將相應地更新,就像Vector實現一樣。
我希望有人可以告訴我為什么這是不同的,因為Vector和ArrayList都實現了List,並且據說應該有類似的行為。
編輯:
感謝您的快速回復! 所有答案都是指ArrayList和Vector之間的同步差異。 但是,我的項目沒有顯式創建新線程。 這可能是我的數據和Swing線程之間的同步問題嗎? 我對線程不太了解......
第二次編輯:
再次感謝大家! 數據和Swing之間的同步很容易回答我的問題,盡管我還有更多細節感興趣,如果有更多的話。
我懷疑差異是由於Vector
是線程安全的而不是ArrayList
。 這會影響其元素更改對不同線程的可見性。 當您更改Vector
的元素時,該更改會立即顯示給其他線程。 (這是因為它的方法使用鎖來同步,這會創建一個內存屏障 ,有效地將線程內存的當前狀態 - 包括其中的最新更改 - 與其他線程同步。)但是,使用ArrayList
這樣的同步不會自動因此,一個線程所做的更改可能僅在以后(並且以任意順序)對其他線程可見,或者根本不可見。
由於Swing本質上是多線程的,因此您需要確保在不同(工作線程,UI)線程之間可以看到數據更改。
矢量是同步的。 它使用synchronized關鍵字來確保訪問它的所有線程都看到一致的結果。 ArrayList未同步。 當一個線程設置ArrayList的元素時,不能保證另一個線程將看到更新。
對Vector元素的訪問是同步的,而不是對ArrayList的訪問。 如果您有不同的線程訪問和修改列表,您將看到兩者之間的不同行為。
我沒有時間測試這段代碼,你的代碼示例仍然很輕(一個很好的全功能樣本會更有幫助 - 我不想寫一個完整的應用程序來測試這個)但我願意打賭如果你把你的調用包裝成'setSelectDeselect'(如你的pastebin中所示),那么ArrayList
和Vector
一樣Vector
:
Runnable selectRunnable = new Runnable()
{
public void run()
{
setSelectDeselect(cat, itemName, selected);
}
};
SwingUtilities.invokeLater(selectRunnable);
您正在事件處理過程中更新ArrayList。 上述代碼將推遲更新,直到事件完成。 我懷疑在這里還有其他的東西可以通過查看其余代碼來表現出來。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.