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