您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java集合框架之如何使用List ArrayList LinkedList”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java集合框架之如何使用List ArrayList LinkedList”吧!
1. List
1.1 List 的常見方法
1.2 代碼示例
2. ArrayList
2.1 介紹
2.2 ArrayList 的構造方法
2.3 ArrayList 底層數組的大小
3. LinkedList
3.1 介紹
3.2 LinkedList 的構造方法
4. 練習題
5. 撲克牌小游戲
方法 | 描述 |
---|---|
boolean add(E e) | 尾插 e |
void add(int index, E element) | 將 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 刪除 index 位置的元素 |
boolean remove(Object o) | 刪除遇到的第一個 o |
E get(int index) | 獲取下標 index 位置的元素 |
E set(int index, E element) | 將下標 index 位置元素設置為 element |
void clear() | 清空 |
boolean contains(Object o) | 判斷 o 是否在線性表中 |
int indexOf(Object o) | 返回第一個 o 所在下標 |
int lastIndexOf(Object o) | 返回最后一個 o 的下標 |
List<E> subList(int fromIndex, int toIndex) | 截取部分 list |
注意: 下面的示例都是一份代碼分開拿出來的,上下其實是有邏輯關系的
示例一: 用 List 構造一個元素為整形的順序表
List<Integer> list = new ArrayList<>();
示例二: 尾插 e
list.add(1); list.add(2); System.out.println(list); // 結果為:[1, 2]
示例三: 將 e 插入到 index 位置
list.add(0,10); System.out.println(list); // 結果為:[10, 1, 2]
示例四: 尾插 c 中的元素
List<Integer> list1=new LinkedList<>(); list1.add(99); list1.add(100); list.addAll(list1); System.out.println(list); // 結果為:[10, 1, 2, 99, 100]
只要是繼承于 Collection 的集合類的元素都可以被插入進去,但要注意傳過來的具體的類型要么是和 list 的具體類型是一樣的,要么是 list 具體類型的子類
示例五: 刪除 index 位置的元素
System.out.println(list.remove(0)); System.out.println(list); // 結果為:10 和 [1, 2, 99, 100]
示例六: 刪除遇到的第一個 o
System.out.println(list.remove((Integer) 100)); System.out.println(list); // 結果為:true 和 [1, 2, 99]
示例七: 獲取下標 index 位置的元素
System.out.println(list.get(0)); // 結果為:1
示例八: 將下標 index 位置元素設置為 element
System.out.println(list.set(2,3)); System.out.println(list); // 結果為:99 和 [1, 2, 3]
示例九: 判斷 o 是否在線性表中
System.out.println(list.contains(1)); // 結果為:true
示例十: 返回第一個 o 所在下標
System.out.println(list.indexOf(1)); // 結果為:0
示例十一: 返回最后一個 o 的下標
list.add(1); System.out.println(list.lastIndexOf(1)); // 結果為:3
示例十二: 截取部分 list
List<Integer> list2=list.subList(1,3); System.out.println(list2); // 結果為:[2, 3]
注意,當我們將 list2 通過 set 更改元素,其實對 list 也會有影響
list2.set(0,5); System.out.println(list2); System.out.println(list); // 結果為:[5, 3] 和 [1, 5, 3, 1]
通過 subList 方法進行的截取,得到的集合的數值指向的地址和原集合中數值的地址是一樣的
ArrayList 類是一個可以動態修改的數組,與普通數組的區別就是它是沒有固定大小的限制,我們可以添加或刪除元素。其繼承了 AbstractList,并實現了 List 接口。LinkedList 不僅實現了 List 接口,還實現了 Queue 和 Deque 接口,可以作為隊列去使用。
ArrayList 類位于 java.util
包中,使用前需要引入它。
方法 | 描述 |
---|---|
ArrayList() | 無參構造 |
ArrayList(Collection<? extends E> c) | 利用其他 Collection 構建 ArrayList |
ArrayList(int initialCapacity) | 指定順序表初始容量 |
示例一:
ArrayList<Integer> list1 = new ArrayList<>();
示例二:
ArrayList<Integer> list2 = new ArrayList<>(10); // 該構造方法就是在構建時就將底層數組大小設置為了10
示例三:
List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); ArrayList<Integer> list3 = new ArrayList<>(list);
Collection<? extends E> c
只要是具體類型都和 list3 是一樣的集合都可以放入轉化成 ArrayList
當我們使用 add 方法給 ArrayList 的對象進行尾插時,突然想到了一個問題:既然 ArrayList 的底層是一個數組,那么這個數組有多大呢?
為了解決這個問題,我進行了如下探索
跳轉到 ArrayList 的定義,我們看到了 elementData
和 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
跳轉到 elementData
的定義,我們可以了解 ArrayList 底層是數組的原因
跳轉到 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
的定義,初步分析得到這個數組其實是空的
為什么這個數組是空的但存儲元素的時候沒有報異常呢?我們再去了解下 add 是怎樣存儲的
通過轉到 ArrayList 的 add 方法的定義
通過定義,不難發現,數組容量和 ensureCapacityInternal
這個東西有關,那我們就看看它的定義
我們看里面的 calculateCapacity
,他有兩個參數,此時數組為空,那么 minCapacity
就為 1。我們再轉到 calculateCapacity
看看它的定義
此時我們就好像可以與之前串起來了,當數組為 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
時,就返回 DeFauLt_CAPACITY
和 minCapacity
(此時為1) 的最大值。DeFauLt_CAPACITY
其實是默認容量的意思,我們可以轉到它的定義看看有多大
DeFauLt_CAPACITY
的值是10,故 calculateCapacity
函數此時的返回值為10,最后我們再確定一下 ensureExplicitCapacity
是干啥的
此時 minCapacity 的值是10,而數組為空時數組長度為0,所以進入 if 語句,執行 grow 方法,我們繼續轉到 grow 的定義
此時我們就可以了解,當我們創建一個 ArrayList 時,其底層數組大小其實是0。當我們第一次 add 的時候,經過 grow ,數組的大小就被擴容為了10。并且這大小為10的容量放滿以后,就會按1.5倍的大小繼續擴容。至于這個數組最大能存放多少,大家可以再轉到 MAX_ARRAY_SIZE
的定義去查看。
LinkedList 類是一種常見的基礎數據結構,是一種線性表,但是并不會按線性的順序存儲數據,而是在每一個節點里存到下一個節點的地址。
Java 的 LinkedList 底層是一個雙向鏈表,位于 java.util
包中,使用前需要引入它
方法 | 描述 |
---|---|
LinkedList() | 無參構造 |
LinkedList(Collection<? extends E> c) | 利用其他 Collection 構建 LinkedList |
示例一:
LinkedList<Integer> list1 = new LinkedList<>();
示例二:
List<Integer> list = new LinkedList<>(); list.add(1); list.add(2); LinkedList<Integer> list2 = new LinkedList<>(list);
Collection<? extends E> c
只要是具體類型都和 list2 是一樣的集合都可以放入轉化成 LinkedList
習題一
題目描述:
霍格沃茨學院有若干學生(學生對象放在一個 List 中),每個學生有一個姓名(String)、班級(String)和考試成績(double)。某次考試結束后,每個學生都獲得了一個考試成績。遍歷 list 集合,并把每個學生對象的屬性都打印出來
本題代碼:
class Student{ private String name; private String classes; private double score; // 重寫構造方法 public Student(String name, String classes, double score) { this.name = name; this.classes = classes; this.score = score; } // 構造 get 和 set 方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClasses() { return classes; } public void setClasses(String classes) { this.classes = classes; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } // 重寫 toString 方法 @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", classes='" + classes + '\'' + ", score=" + score + '}'; } } public class TestDemo { public static void main(String[] args) { ArrayList<Student> students = new ArrayList<>(); students.add(new Student("哈利波特","大二班",95.5)); students.add(new Student("赫敏格蘭杰","小三班",93)); students.add(new Student("羅恩韋斯萊","小二班",91)); for(Student s: students){ System.out.println(s); } } } // 結果為: // Student{name='哈利波特', classes='大二班', score=95.5} // Student{name='赫敏格蘭杰', classes='小三班', score=93.0} // Student{name='羅恩韋斯萊', classes='小二班', score=91.0}
習題二
題目描述:
有一個 List 當中存放的是整形的數據,要求使用 Collections.sort
對 List 進行排序
該題代碼:
public class TestDemo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(3); list.add(7); list.add(1); list.add(6); list.add(2); Collections.sort(list); System.out.println(list); } } // 結果為:[1, 2, 3, 6, 7]
補充:
Collections 是一個工具類,sort 是其中的靜態方法,它是用來對 List 類型進行排序的
注意:
如果具體的類是類似于習題一那樣的 Student 類,該類中含有多個屬性,那就不能直接使用這個方法。要對 comparator
或者 comparable
接口進行重寫,確定比較的是哪個屬性才行
習題三
題目描述:
輸出刪除了第一個字符串當中出現的第二個字符串中的字符的字符串,例如
String str1 = "welcome to harrypotter"; String str2 = "come"; // 結果為:wl t harrypttr
希望本題可以使用集合來解決
該題代碼:
public static void removeS(String str1, String str2){ if(str1==null || str2==null){ return; } List<Character> list = new ArrayList<>(); int lenStr1=str1.length(); for(int i=0; i<lenStr1; i++){ char c = str1.charAt(i); if(!str2.contains(c+"")){ list.add(c); } } for(char ch: list){ System.out.print(ch); } }
我們可以通過上述所學,運用 List 的知識,去寫一個關于撲克牌的邏輯代碼(如:獲取一副牌、洗牌、發牌等等)
class Card{ private String suit; // 花色 private int rank; // 牌面值 public Card(String suit, int rank){ this.suit=suit; this.rank=rank; } @Override public String toString() { return "[ "+suit+" "+rank+" ] "; } } public class TestDemo { public static String[] suits = {"?", "?", "?", "?"}; // 獲取一副牌 public static List<Card> getNewCards(){ // 存放 52 張牌 List<Card> card = new ArrayList<>(); for(int i=0; i<4; i++){ for(int j=1; j<=13; j++) { card.add(new Card(suits[i], j)); } } return card; } public static void swap(List<Card> card, int i, int j){ Card tmp = card.get(i); card.set(i, card.get(j)); card.set(j, tmp); } // 洗牌 public static void shuffle(List<Card> card){ int size = card.size(); for(int i=size-1; i>0; i--){ Random random = new Random(); int randNum = random.nextInt(i); swap(card, i, randNum); } } public static void main(String[] args) { // 得到一副新的牌 List<Card> cardList = getNewCards(); System.out.println("已獲取新的撲克牌"); System.out.println("洗牌:"); shuffle(cardList); System.out.println(cardList); System.out.println("抓牌:(3個人,每人輪流抓牌總共抓5張)"); List<Card> hand1 = new ArrayList<>(); List<Card> hand2 = new ArrayList<>(); List<Card> hand3 = new ArrayList<>(); List<List<Card>> hands = new ArrayList<>(); hands.add(hand1); hands.add(hand2); hands.add(hand3); for(int i=0; i<5; i++){ for(int j=0; j<3; j++){ Card card = cardList.remove(0); hands.get(j).add(card); } } System.out.println("第一個人的牌:"+hand1); System.out.println("第二個人的牌:"+hand2); System.out.println("第三個人的牌:"+hand3); } } /** 結果為: 已獲取新的撲克牌 洗牌: [[ ? 9 ] , [ ? 6 ] , [ ? 8 ] , [ ? 2 ] , [ ? 6 ] , [ ? 4 ] , [ ? 11 ] , [ ? 9 ] , [ ? 8 ] , [ ? 5 ] , [ ? 8 ] , [ ? 10 ] , [ ? 1 ] , [ ? 12 ] , [ ? 10 ] , [ ? 7 ] , [ ? 12 ] , [ ? 12 ] , [ ? 7 ] , [ ? 13 ] , [ ? 6 ] , [ ? 5 ] , [ ? 3 ] , [ ? 5 ] , [ ? 11 ] , [ ? 12 ] , [ ? 7 ] , [ ? 3 ] , [ ? 5 ] , [ ? 13 ] , [ ? 1 ] , [ ? 8 ] , [ ? 10 ] , [ ? 4 ] , [ ? 4 ] , [ ? 7 ] , [ ? 1 ] , [ ? 1 ] , [ ? 3 ] , [ ? 11 ] , [ ? 13 ] , [ ? 9 ] , [ ? 13 ] , [ ? 10 ] , [ ? 6 ] , [ ? 11 ] , [ ? 3 ] , [ ? 2 ] , [ ? 2 ] , [ ? 2 ] , [ ? 4 ] , [ ? 9 ] ] 抓牌:(3個人,每人輪流抓牌總共抓5張) 第一個人的牌:[[ ? 9 ] , [ ? 2 ] , [ ? 11 ] , [ ? 5 ] , [ ? 1 ] ] 第二個人的牌:[[ ? 6 ] , [ ? 6 ] , [ ? 9 ] , [ ? 8 ] , [ ? 12 ] ] 第三個人的牌:[[ ? 8 ] , [ ? 4 ] , [ ? 8 ] , [ ? 10 ] , [ ? 10 ] ] */
上述代碼中有一處代碼是這樣寫的 List<List<Card>>
,其實不難理解,這個類型其實就是 List 中存放的每個元素都是一個 List 類型的,并且每一個 List 元素中的元素都是 Card 類型,類似于二維數組。
感謝各位的閱讀,以上就是“Java集合框架之如何使用List ArrayList LinkedList”的內容了,經過本文的學習后,相信大家對Java集合框架之如何使用List ArrayList LinkedList這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。