JavaRush /Java Blog /Random-TW /Java中的ArrayList圖片

Java中的ArrayList圖片

在 Random-TW 群組發布
你好!今天的講座ArrayList,一方面比之前的講座更簡單,另一方面也比之前的講座更難。 圖片中的 ArrayList 工作 - 1這更加困難,因為今天我們將深入了解「幕後」ArrayList並研究它在操作過程中會發生什麼。另一方面,本次講座中幾乎沒有代碼——主要是圖片和解釋。那麼,讓我們開始吧:) 如您所知,ArrayList'a 內部有一個普通數組,充當資料存儲。在大多數情況下,我們不指定清單的確切大小。但內部數組必須有一定的大小!這是真實的。它的預設大小是 [10]
public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
}
圖片中使用 ArrayList - 2首先,讓我們來看看新增元素是什麼樣子的。首先,檢查內部陣列是否有足夠的空間以及是否可以再容納一個元素。如果有空間,則新元素將新增至清單末端。當我們說「到最後」時,我們並不是指數組的最後一個單元格(這會很奇怪)。這是指最後一個目前元素旁邊的儲存格。它的索引將等於cars.size()。我們的清單目前為空 ( cars.size() = 0)。因此,一個新元素將被添加到索引為的單元格中0
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
圖片中使用 ArrayList - 3這裡一切都清楚了。如果在中間,即幾個元素之間進行插入,會發生什麼情況?
public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
   Car ferrari = new Car("Ferrari 360 Spider");
   Car bugatti = new Car("Bugatti Veyron");
   Car lambo = new Car("Lamborghini Diablo");
   Car ford = new Car("Ford Modneo");

   cars.add(ferrari);
   cars.add(bugatti);
   cars.add(lambo);

   cars.add(1, ford);//добавляем ford в ячейку 1, которая уже занята
}
同樣,它首先檢查數組中是否有足夠的空間。如果有足夠的空間,元素將從我們插入新元素的單元格開始向右移動。我們貼上到索引為 1 的單元格中。也就是說,單元格 3 中的元素被複製到單元格 4 中,元素 2 被複製到單元格 3 中,元素 1 被複製到單元格 2 中。 圖片中使用 ArrayList - 4之後,我們的新元素被貼到位。前一個元素 ( bugatti) 已從此處複製到新位置。 圖片中使用 ArrayList - 5現在讓我們弄清楚如果數組中沒有空間可插入,這個過程將如何發生。 圖片中使用 ArrayList - 6當然,首先要檢查是否有足夠的空間。如果發現空間不足,ArrayList則會在 'a 內建立一個大小為 (OldArray 的大小 * 1.5) + 1 的新陣列。在我們的範例中,新陣列的大小為 16 個儲存格。所有當前元素將立即複製到那裡。 圖片中使用 ArrayList - 7舊的陣列將被垃圾收集器刪除,只保留新的、擴充的陣列。現在有新元素的可用空間。我們將其貼到已被佔用的儲存格 3 中。現在熟悉的程序開始了。從索引 3 開始的所有元素都向右移動一個儲存格,並悄悄新增一個元素。 圖片中使用 ArrayList - 8現在插入成功了!我們整理了插入。現在我們來談談刪除元素。正如您所記得的,在使用陣列時,我們遇到了一個問題:當我們刪除它們時,「洞」仍然存在於其中。唯一的解決方案是每次刪除元素時 將元素向左移動,並且您必須自己編寫移動程式碼。ArrayList工作原理相同,但在其中該機制已經自動實現。 圖片中使用 ArrayList - 9看起來是這樣的: 圖片中使用 ArrayList - 10最後我們得到了想要的結果: 圖片中使用 ArrayList - 11元素lambo被成功刪除。這裡我們從中間進行了刪除。顯然,從清單末尾刪除會更快,因為刪除所需元素時不會移動所有其他元素。我們再看一下內部數組的大小以及它在記憶體中的儲存情況。 數組擴充是一個需要消耗一定資源的過程。ArrayList因此,如果您確定它至少有 100 個元素,則 不應使用預設大小進行建立。當您插入第 100 個元素時,內部陣列將擴展6 倍,每次都會傳輸所有元素。
  • 從 10 個元素到 16 個
  • 從 16 個元素增加到 25 個
  • 25 至 38
  • 從 38 到 58
  • 從 58 到 88
  • 從 88 到 133(根據公式(舊數組的大小 * 1.5)+ 1)
當然,這在資源方面是相當昂貴的。因此,如果您已經知道一些(至少大約)儲存元素的數量,最好立即建立一個具有一定大小的陣列的清單:
ArrayList<Car> cars = new ArrayList<>(100);
現在,一個包含 100 個元素的陣列將立即分配在記憶體中,這將更加高效,因為資源不會浪費在擴充功能上。硬幣還有另一面。 當從內部數組中刪除物件時ArrayList,大小不會自動減少。 例如,我們有ArrayList一個內部數組,有 88 個元素,它已完全填滿: 圖片中使用 ArrayList - 13在程式運行過程中,我們從中刪除了 77 個元素,只剩下 11 個元素: 圖片中使用 ArrayList - 14你已經猜到問題是什麼了嗎?當然,記憶體使用效率低!我們只使用 11 個單元,而我們為 88 個元素分配了記憶體 - 這比我們需要的多 8 倍!要在這種情況下進行最佳化,可以使用特殊的類別方法ArrayList- trimToSize()。它將內部數組的長度「剪切」為目前儲存在其中的元素數量。 圖片中使用 ArrayList - 15現在已根據需要分配了盡可能多的記憶體!:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION