CodeGym /Java Blog /Toto sisi /Java列表
John Squirrels
等級 41
San Francisco

Java列表

在 Toto sisi 群組發布
Java Collection Framework 包含非常有用的接口和實現它們以處理數據結構的類。可以說這是最重要的JDK框架之一。列表界面非常流行。因為在編程中沒有各種列表,它是必不可少的。在本文中,我們將介紹此接口、Java List 方法和實現。

Java 列表接口

列表最重要的是它是一個有序的集合。您也可以將其稱為序列。在 Java 中,列表是同構的,即列表中的元素具有相同的數據類型。Java List接口繼承自Collection,它繼承了它的所有操作。除了它們之外,List 中還可以進行以下操作:
  • 位置訪問。每個元素都有一個索引,可以根據它們的位置進行操作。在列表中。也就是說,您可以添加、排除和修改元素。
  • 搜索。您可以通過其內容在列表中找到一個元素並返回其索引。
  • 迭代。List 的順序性質允許使用迭代方法 (listIterator)。
  • 遠景。sublist 方法對列表執行任意範圍的操作。

Java 列表方法

以上操作暴露在Java List接口的方法中。這是其中的一些:
方法 描述
添加(E元素) 此方法將元素元素添加到此列表的末尾。
添加(整數索引,元素) 該方法在列表中的特定索引處添加一個元素。如果傳遞了所需的參數,它會將元素添加到列表的末尾。
addAll(int index, Collection 集合) 將給定集合中的所有元素添加到列表中。如果傳遞單個參數,它會將給定集合的所有元素添加到列表的末尾。
尺寸() 返回列表的大小(列表中元素的數量)。
得到(整數索引) 返回指定索引處的元素。
集合(整數索引,元素) 用新元素替換給定索引處的元素,並返回被新元素替換的元素。
刪除(整數索引) 從指定索引中刪除一個元素。
刪除(元素) 刪除列表中給定元素的第一次出現。
清除() 從列表中刪除所有元素。
索引(元素) 返回給定元素的第一次出現。如果列表中不存在該元素,則返回-1
lastIndexOf(元素) 返回給定元素的最後一次出現。如果列表中不存在該元素,則返回-1
等於(元素) 比較給定元素與列表元素的相等性。
哈希碼() 返回給定列表的哈希碼值。
是空的() 檢查列表是否為空。如果列表為空,則返回 true。
包含(元素) 檢查列表是否包含元素。如果列表包含該元素,則返回 true。
包含所有(集合集合) 檢查列表是否包含所有元素集合。
排序(比較器比較) 根據給定的比較器對列表的元素進行排序。
子列表(int fromIndex,int toIndex) 返回此列表中指定的 fromIndex(包含)和 toIndex(不包含)之間的部分視圖。

列表實現

因為 List 是一個接口,所以程序需要創建它的具體實現。您可以在 Java Collections API 中的以下 List 實現之間進行選擇:
  • java.util.ArrayList
  • java.util.鍊錶
  • java.util.Vector
  • java.util.堆棧
最流行的 List 接口實現稱為 ArrayList。少得多,但您仍然可以在實際任務中看到 LinkedList 的使用,但是 Vector 和 Stack 在道德上已經過時了很長時間,因此您很可能只會在具有古老遺留代碼的項目中找到它們。

列表接口聲明

您可以通過以下方式之一在 Java 程序中聲明一個列表:

List<String> myList = new ArrayList();
List myList1 = new ArrayList();
List myList3 = new ArrayList<String>();
ArrayList arrayList = new ArrayList();
最好通過接口聲明一個新列表。同樣,您可以聲明 List 的其他實現。最短路線:

Vector myVector = new Vector;
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
通過這樣的聲明,此類列表元素的數據類型在列表初始化期間確定,即在向其中添加元素時確定。

List myList = new ArrayList<String>();
Vector myVector = new Vector();
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
stack.add("Paul");
linkedList.add(1);
myVector.add(1.2f);
myList.add('a');
現在只有字符串可以添加到我們的堆棧中,整數可以添加到linkedList,浮點數可以添加到myVector,而myList是一個字符列表。

ArrayList 的工作原理

如果您已經熟悉常規數組,那麼您對 ArrayList 也多少有些熟悉。ArrayList其實是一個動態數組,裡面是一個普通的數組。該數組充當數據存儲。ArrayList 僅存儲引用類型、任何對象,包括第三方類、字符串、輸出流和其他集合。包裝類用於在 ArrayList 中存儲原始數據類型。創建列表時,我們可以立即設置它的大小,但在大多數情況下我們不會這樣做。默認情況下,ArrayList 大小 = 10。向 ArrayList 添加新元素是什麼樣子的?首先,開始檢查內部數組中是否有足夠的空間以及是否可以容納更多元素。如果有空格,則將新元素添加到列表的末尾,即添加到最後一個元素之後的單元格。它的索引將是 arraylist.size()。如果我們剛剛創建了我們的列表並且它是空的,這意味著 arrayList.size() = 0。相應地,一個新元素將被添加到索引為 0 的單元格中。如果發現沒有足夠的空間,一個新的在 ArrayList 內部創建數組,大小為(OldArray 的大小 * 1.5)+ 1。同樣的原理,插入發生在列表的中間,但同時插入元素後面的所有元素都是向右移動。因此,如果我們在數組中有 5 個元素,並且我們需要將一個元素插入單元格編號 2(即第三個),則 0 和 1 數組元素保留在原位,新元素出現在單元格 2 中,並且它的前身進入第三個牢房,依此類推。一個新元素將被添加到索引為 0 的單元格中。如果發現沒有足夠的空間,則會在 ArrayList 中創建一個新數組,其大小為(OldArray * 1.5 的大小)+ 1。同樣原則上,插入發生在列表的中間,但同時插入元素後面的所有元素都向右移動。因此,如果我們在數組中有 5 個元素,並且我們需要將一個元素插入單元格編號 2(即第三個),則 0 和 1 數組元素保留在原位,新元素出現在單元格 2 中,並且它的前身進入第三個牢房,依此類推。一個新元素將被添加到索引為 0 的單元格中。如果發現沒有足夠的空間,則會在 ArrayList 中創建一個新數組,其大小為(OldArray * 1.5 的大小)+ 1。同樣原則上,插入發生在列表的中間,但同時插入元素後面的所有元素都向右移動。因此,如果我們在數組中有 5 個元素,並且我們需要將一個元素插入單元格編號 2(即第三個),則 0 和 1 數組元素保留在原位,新元素出現在單元格 2 中,並且它的前身進入第三個牢房,依此類推。插入發生在列表的中間,但同時插入元素之後的所有元素都向右移動。因此,如果我們在數組中有 5 個元素,並且我們需要將一個元素插入單元格編號 2(即第三個),則 0 和 1 數組元素保留在原位,新元素出現在單元格 2 中,並且它的前身進入第三個牢房,依此類推。插入發生在列表的中間,但同時插入元素之後的所有元素都向右移動。因此,如果我們在數組中有 5 個元素,並且我們需要將一個元素插入單元格編號 2(即第三個),則 0 和 1 數組元素保留在原位,新元素出現在單元格 2 中,並且它的前身進入第三個牢房,依此類推。

Java List實例(Arraylist實現)


import java.util.*;

public class ArrayListExample2 {
   public static void main(String[] args) {
       List<String> myFriendsList = new ArrayList();
       //we created list of some objects 
       System.out.println( "the size of myList before init = " + myFriendsList.size());
       myFriendsList.add("Alex");
       myFriendsList.add("Tanya");
       myFriendsList.add("Veloxy");
       myFriendsList.add("Alex");
       myFriendsList.add("Andrew");
       System.out.println(myFriendsList);
       System.out.println( "the size of myList after init = " + myFriendsList.size());

       myFriendsList.add("Ihor");
       System.out.println(myFriendsList);
       System.out.println("the size of my list = " +  myFriendsList.size());


       //here the program will print out the first appearance of "Alex" element
       System.out.println(myFriendsList.indexOf("Alex"));
       //program will print out the first appearance of "Alex" element starting from the element 0

       myFriendsList.remove(3);
       System.out.println(myFriendsList.get(3));
       System.out.println("after removing one of Alex's there is only one Alex: " + myFriendsList);
       System.out.println(myFriendsList.get(1));



       myFriendsList.clear();
       System.out.println("the size of the vector after clear method = " +  myFriendsList.size());

   }
}
這是該程序的輸出:
初始化前 myList 的大小 = 0 [Alex, Tanya, Veloxy, Alex, Andrew] 初始化後 myList 的大小 = 5 [Alex, Tanya, Veloxy, Alex, Andrew, Ihor] 我列表的大小 = 6 0 Andrew 之後刪除 Alex 的一個,只有一個 Alex:[Alex, Tanya, Veloxy, Andrew, Ihor] Tanya 清除方法後向量的大小 = 0 進程完成,退出代碼為 0

鍊錶的工作原理

在 LinkedList 中,元素實際上是同一條鏈中的鏈接。每個元素,除了它存儲的數據之外,還有一個指向前一個和下一個元素的鏈接。這些鏈接允許您從一個元素導航到另一個元素。迭代器支持雙向遍歷。實現在列表的開頭、中間和結尾處獲取、刪除和插入的方法。允許您添加任何元素,包括 null。LinkedList 實現了兩個接口——不僅是 List,還有 Deque。這提供了從任何元素(甚至是空元素)創建雙向隊列的能力。鍊錶中放置的每個對像都是一個節點(node)。每個節點包含一個元素,一個指向上一個和下一個節點的鏈接。事實上,鍊錶由一系列節點組成,每個節點都被設計用來存儲創建時定義的類型的對象。

代碼示例


import java.util.*;
public class LinkedListTest {

       public static void main(String args[]){

           List myLinkedList= new LinkedList<Integer>();
           myLinkedList.add(1);
           myLinkedList.add(2);
           myLinkedList.add(4);
           System.out.println("three added elements: " + myLinkedList);
           myLinkedList.add(5);
           myLinkedList.remove(1);
           System.out.println(myLinkedList);
           myLinkedList.size(); //3
           
           //add new element at the specified position:
           myLinkedList.add(2,7);
           System.out.println(myLinkedList);
                }
       }
輸出在這裡:
三個添加的元素:[1, 2, 4] [1, 4, 5] [1, 4, 7, 5]

矢量代碼示例

Vector 也是一個動態數組實現,與 ArrayList 非常相似,但同步並具有集合框架不包含的一些遺留方法。這是此類用法的一個簡單示例。

import java.util.Vector;

public class VectorExample1 {

   public static void main(String[] args) {
       Vector vector = new Vector();
       System.out.println("the size of the empty vector = " +  vector.size());
       vector.add("Alex");
       vector.add("Tanya");
       vector.add("Andrew");
       System.out.println(vector);
       vector.add("Alex");
       vector.add("Ihor");
       System.out.println(vector);
       System.out.println("the size of the vector = " +  vector.size());
       System.out.println("the first element of the vector = " + vector.firstElement());

       //here the program will print out the first appearance of "Johnny" element
       System.out.println(vector.indexOf("Andrew"));
       //program will print out the first appearance of "Johnny" element starting from the element 1
       System.out.println(vector.indexOf("Alex", 1));
       System.out.println(vector);
       vector.clear();
       System.out.println("the size of the vector after clear method = " +  vector.size());

   }
}
輸出是:
空向量的大小 = 0 [Alex, Tanya, Andrew] [Alex, Tanya, Andrew, Alex, Ihor] 向量的大小 = 5 向量的第一個元素 = Alex 2 3 [Alex, Tanya, Andrew, Alex, Ihor] 清除方法後向量的大小 = 0 進程完成,退出代碼為 0

Java Stack 類代碼示例


import java.util.Stack;

public class StackTest {
   public static void main(String[] args) {
       Stack stack = new Stack();
       System.out.println(stack.isEmpty());
       stack.add("Paul");
       stack.add("Johnny");
       stack.add("Alex");
       System.out.println(stack.isEmpty());
       stack.push("Andrew");
       System.out.println(stack);
       stack.pop();
       System.out.println(stack);
   }
}
Stack不僅有add()remove()方法,還有push和pop,它們是此類數據結構的經典。堆棧遵循“先進後出”的規則——這就是這樣一個反隊列。因此,pop 操作彈出最後放入堆棧的元素。這是我們示例的輸出:
真假 [保羅、約翰尼、亞歷克斯、安德魯] [保羅、約翰尼、亞歷克斯]
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION