還在深入瞭解集合框架(ArrayList、LinkedList)原始碼?先看看這篇文章吧
寫在前面,Java基礎系列文章都是作者基於b站尚矽谷的Java基礎視訊所做的筆記,沒有時間的同學可以認真看看,如果有時間的同學,還是建議看看視訊,畢竟筆記說到底還是自己的東西,每個人的習慣也是不一樣的,所以為了自己,學就對了,加油!
也請各位同學,如果感覺對自己有幫助,可以幫忙給個一鍵三連,謝謝!
1.Java集合框架概述
1.1 集合框架與陣列的對比和概述
/**
* 一、集合框架的概述
*
* 1.集合、陣列都是對多個資料進行儲存操作的結構,簡稱Java容器。
* 說明:此時的儲存,主要指的是記憶體層面的儲存,不涉及到持久化的儲存(.txt,.jpg,.avi 到資料庫中)
*
* 2.1 陣列在儲存多個資料方面的特點:
* > 一旦初始化以後,其長度就確定了。
* > 陣列一旦定義好,其元素的型別也就確定了。我們也就只能操作指定型別的資料了。
* 比如:String[] arr; int[] arr1; Object[] arr2;
* 2.2 陣列在儲存多個資料方面的缺點:
* > 一旦初始化以後,其長度就不可修改。
* > 陣列中提供的方法非常有限,
* 對於新增、刪除、插入資料等操作,非常不便,同時效率不高。
* > 獲取陣列中實際元素的個數的需求,陣列沒有現成的屬性或方法可用
* > 陣列儲存資料的特點:有序、可重複。(對於無序、不可重複的需求,陣列不能滿足)
*
* 2.3 集合儲存的優點:解決陣列儲存資料方面的弊端
*/
1.2 集合的使用場景
1.3 集合框架涉及到的API
Java 集合可分為Collection
和 Map
兩種體系
Collection介面
:單列資料
,定義了存取一組物件的方法的集合List
:元素有序
、可重複的集合
Set
:元素無序
、不可重複的集合
Map介面
:雙列資料
,儲存具有對映關係“key-value鍵值對
”的集合- Collection介面繼承樹
- Map介面繼承樹
/**
* 二、集合框架
* |----Collection介面:單列集合,用來儲存一個一個的物件
* |----List介面:儲存有序的、可重複的資料。 -->“動態”陣列
* |----ArrayList、LinkedList、Vector
*
* |----Set介面:儲存無序的、不可重複的資料 -->高中講的“集合”
* |----HashSet、LinkedHashSet、TreeSet
*
* |----Map介面:雙列集合,用來儲存一對(key - value)一對的資料 -->高中函式:y = f(x) (x對應key,y對應value)
* |----HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
*/
2.Collection介面方法
Collection
介面是List、Set 和Queue 介面
的父介面
,該介面裡定義的方法既可用於操作Set 集合,也可用於操作List 和Queue 集合。- JDK不提供此介面的任何直接實現,而是提供更具體的子介面(如:Set和List)實現。
- 在Java5 之前,Java 集合會丟失容器中所有物件的資料型別,把所有物件都當成Object 型別處理;從JDK 5.0 增加了
泛型
以後,Java 集合可以記住
容器中物件的資料型別
。
2.1 Collection介面中的常用方法1
- 新增
add(Object obj)
addAll(Collection coll)
- 獲取有效元素的個數
intsize( )
- 清空集合
voidclear( )
- 是否是空集合
boolean isEmpty( )
- 是否包含某個元素
boolean contains(Object obj)
:是通過元素的equals方法
來判斷是否是同一個物件
boolean containsAll(Collection c)
:也是呼叫元素的equals方法
來比較的。拿兩個集合的元素挨個比較
。
- 刪除
boolean remove(Object obj)
:通過元素的equals方法判斷是否是要刪除的那個元素。只會刪除找到的第一個元素
boolean removeAll(Collection coll)
:取當前集合的差集
- 取兩個集合的交集
boolean retainAll(Collection c)
:把交集的結果存在當前集合中,不影響c
- 集合是否相等
- boolean equals(Object obj)
- 轉成
物件陣列
Object[] toArray( )
- 獲取集合物件的
雜湊值
hashCode( )
遍歷
iterator( )
:返回迭代器物件,用於集合遍歷
/**
* 三、Collection介面中方法的使用
*/
public class CollectionTest {
@Test
public void test1(){
Collection coll = new ArrayList();
//add(Object e):將元素e新增到集合coll中
coll.add("AA");
coll.add("BB");
coll.add(123);//自動裝箱,將int型別包裝成Integer型別
coll.add(new Date());
//size():獲取新增的元素的個數
System.out.println(coll.size());//4
//addAll(Collection colls):將colls集合中的元素新增到當前的集合中
Collection colls = new ArrayList();
colls.add(456);
colls.add("CC");
coll.addAll(colls);
System.out.println(coll.size());//6
System.out.println(coll.toString());
//clear():清空集合中的元素
coll.clear();
//isEmpty():判斷當前集合是否為空
System.out.println(coll.isEmpty()); //true
System.out.println("清空集合中的元素後:" + coll); //[]
}
}
2.2 Collection介面中的常用方法2
Person類
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("Person equals()....");
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
測試類
/**
* Collection介面中宣告的方法的測試
*
* contains(Object obj),如果要比較obj與集合中某個元素的"內容"是否相等,
* 要求當前obj型別要重寫equals()方法,因為equals()比較的就是兩個物件的內容是否相等
*
* 結論:
* 向Collection介面的實現類的物件中新增資料obj時,要求obj所在類要重寫equals()方法.
*/
public class CollectionTest {
@Test
public void test1(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
// Person p = new Person("Jerry",20);
// coll.add(p);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//1.contains(Object obj):判斷當前集合中是否包含obj
//我們在判斷時會呼叫obj物件所在類的equals()方法。
boolean contains = coll.contains(123); //true,Integer型別重寫了equals方法
System.out.println(contains); //true
System.out.println(coll.contains(new String("Tom")));//true,String類重寫了equals方法
// System.out.println(coll.contains(p));//true
//如果Person類重寫了equals()方法,則比較內容是否相等
System.out.println(coll.contains(new Person("Jerry",20)));
//2.containsAll(Collection colls):判斷形參colls中的所有元素是否都存在於當前集合中。
Collection colls = Arrays.asList(123,4567);
//判斷coll集合是否包含colls的所有元素
System.out.println(coll.containsAll(colls)); //false
}
}
2.3 Collection介面中的常用方法3
Person類
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("Person equals()....");
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
測試類
/**
* Collection介面中宣告的方法的測試
*
* contains(Object obj),如果要比較obj與集合中某個元素的"內容"是否相等,
* 則當前obj型別要重寫equals()方法,因為equals()比較的就是兩個物件的內容是否相等
*
* 結論:
* 向Collection介面的實現類的物件中新增資料obj時,要求obj所在類要重寫equals()方法.
*/
public class CollectionTest {
@Test
public void test2(){
//3.remove(Object obj):從當前集合中移除obj元素。
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
coll.remove(1234);
System.out.println(coll);
coll.remove(new Person("Jerry",20));
System.out.println(coll);
//4. removeAll(Collection coll1):差集:從當前集合中移除coll1中所有的元素。
Collection coll1 = Arrays.asList(123,456);
coll.removeAll(coll1);
System.out.println(coll);
}
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//5.retainAll(Collection coll1):交集:獲取當前集合和coll1集合的交集,並返回給當前集合
// Collection coll1 = Arrays.asList(123,456,789);
// coll.retainAll(coll1);
// System.out.println(coll); //123,456
//6.equals(Object obj):要想返回true,需要當前集合和形參集合的元素都相同。
Collection coll1 = new ArrayList();
coll1.add(123);
coll1.add(456);
coll1.add(new Person("Jerry",20));
coll1.add(new String("Tom"));
coll1.add(false);
System.out.println(coll.equals(coll1)); //true
}
}
2.4 Collection介面中的常用方法4
Person類
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("Person equals()....");
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
測試類
/**
* Collection介面中宣告的方法的測試
*
* contains(Object obj),如果要比較obj與集合中某個元素的"內容"是否相等,
* 則當前obj型別要重寫equals()方法,因為equals()比較的就是兩個物件的內容是否相等
*
* 結論:
* 向Collection介面的實現類的物件中新增資料obj時,要求obj所在類要重寫equals()方法.
*/
public class CollectionTest {
@Test
public void test4(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//7.hashCode():返回當前物件的雜湊值
System.out.println(coll.hashCode());
//8.集合 --->陣列:toArray()
Object[] arr = coll.toArray();
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
//擴充:陣列 --->集合:呼叫Arrays類的靜態方法asList()
List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
System.out.println(list);
//注意:基本陣列型別的陣列會被看成整體的一個元素,需要用包裝類的陣列
List arr1 = Arrays.asList(new int[]{123, 456});
System.out.println(arr1.size());//1
List arr2 = Arrays.asList(new Integer[]{123, 456});
System.out.println(arr2.size());//2
//9.iterator():返回Iterator介面的例項,用於遍歷集合元素。放在IteratorTest.java中測試
}
}
3.Iterator迭代器介面
Iterator
物件稱為迭代器(設計模式的一種),主要用於遍歷Collection 集合中的元素
。- GOF給迭代器模式的定義為:提供一種方法訪問一個容器(container)物件中各個元素,而又無需暴露該物件的內部細節。迭代器模式,就是為容器而生。類似於“公交車上的售票員”、“火車上的乘務員”、“空姐”。
Collection介面
繼承了java.lang.Iterable介面
,該介面有一個iterator( )
方法,那麼所有實現了Collection介面的集合類都有一個iterator( )
方法,用於返回一個實現了Iterator介面的物件。Iterator 僅用於遍歷集合
,Iterator本身並不提供承裝物件的能力
。如果需要建立Iterator 物件,則必須有一個被迭代的集合。- 集合物件每次呼叫iterator( )方法都得到一個全新的迭代器物件,
預設遊標都在集合的第一個元素之前
。
3.1 使用Iterator遍歷Collection
/**
* 集合元素的遍歷操作,使用迭代器Iterator介面
* 1.內部的方法:hasNext() 和 next()
* hasNext():沒有指標下移操作,只是判斷是否存在下一個元素
* next():指標下移,返回該指標所指向的元素
* 2.集合物件每次呼叫iterator()方法都得到一個全新的迭代器物件,
* 預設遊標都在集合的第一個元素之前。
* 3.內部定義了remove(),可以在遍歷的時候,刪除集合中的元素。
* 注意:此方法不同於集合直接呼叫remove()方法
*/
public class IteratorTest {
@Test
public void test1(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//建立迭代器物件
Iterator iterator = coll.iterator();
//方式一:
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// //報異常:NoSuchElementException
// System.out.println(iterator.next());
//方式二:不推薦
// for(int i = 0;i < coll.size();i++){
// System.out.println(iterator.next());
// }
//方式三:推薦
//hasNext():判斷是否還有下一個元素
while(iterator.hasNext()){
//next():①指標下移 ②將下移以後集合位置上的元素返回
System.out.println(iterator.next());
}
}
}
3.2 迭代器Iterator的執行原理
3.3 Iterator遍歷集合的兩種錯誤寫法
/**
* 集合元素的遍歷操作,使用迭代器Iterator介面
* 1.內部的方法:hasNext() 和 next()
* hasNext():沒有指標下移操作,只是判斷是否存在下一個元素
* next():指標下移,返回該指標所指向的元素
* 2.集合物件每次呼叫iterator()方法都得到一個全新的迭代器物件,
* 預設遊標都在集合的第一個元素之前。
* 3.內部定義了remove(),可以在遍歷的時候,刪除集合中的元素。
* 注意:此方法不同於集合直接呼叫remove()方法
*/
public class IteratorTest {
@Test
public void test2(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//錯誤方式一:會報NoSuchElementException異常
// Iterator iterator = coll.iterator();
// while((iterator.next()) != null){
// System.out.println(iterator.next());
// }
//錯誤方式二:每次建立迭代器物件,指標就返回到第一個元素之前,使用while就會出現死迴圈
//集合物件每次呼叫iterator()方法都得到一個全新的迭代器物件,
// 預設遊標都在集合的第一個元素之前。
while (coll.iterator().hasNext()){
System.out.println(coll.iterator().next());
}
}
}
3.4 Iterator迭代器remove( )的使用
/**
* 集合元素的遍歷操作,使用迭代器Iterator介面
* 1.內部的方法:hasNext() 和 next()
* hasNext():沒有指標下移操作,只是判斷是否存在下一個元素
* next():指標下移,返回該指標所指向的元素
* 2.集合物件每次呼叫iterator()方法都得到一個全新的迭代器物件,
* 預設遊標都在集合的第一個元素之前。
* 3.內部定義了remove(),可以在遍歷的時候,刪除集合中的元素。
* 該方法移除的是iterator.next()方法最後訪問的元素
* 注意:此方法不同於集合直接呼叫remove()方法
*/
public class IteratorTest {
//測試Iterator中的remove()方法
//如果還未呼叫next()或 在上一次呼叫 next 方法之後已經呼叫了 remove 方法,
// 再呼叫remove都會報IllegalStateException。
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//刪除集合中的元素"Tom"
Iterator iterator = coll.iterator();
while (iterator.hasNext()){
//如果還未呼叫next(),就已經呼叫了remove()方法,
//會報IllegalStateException異常
// iterator.remove();
Object obj = iterator.next();
if("Tom".equals(obj)){
iterator.remove(); //刪除元素
// 再次呼叫remove()方法,也會報IllegalStateException異常
// iterator.remove();
}
}
//遍歷集合
//注意:上面的while迴圈結束後,指標已經指向了最後的位置,
//需要重新建立一個iterator物件,從第一個元素之前的位置開始遍歷
iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
//使用Iterator迭代器刪除集合中的所有元素
@Test
public void test4() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
System.out.println("未刪除元素之前:"+coll.size()); //5
Iterator iterator = coll.iterator();
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
}
System.out.println("刪除元素之後:"+coll.size()); //0
}
}
注意:
- Iterator可以刪除集合的元素,但是是遍歷過程中通過迭代器物件的
remove( )方法
,不是集合物件的remove方法。 - 如果還未呼叫next( )或在上一次呼叫next方法之後已經呼叫了remove方法,再呼叫remove都會報
IllegalStateException
。
3.5 新特性foreach迴圈遍歷集合或陣列
- Java 5.0 提供了
foreach迴圈
迭代訪問Collection和陣列
。 - 遍歷操作不需獲取Collection或陣列的長度,無需使用索引訪問元素。
- 遍歷集合的
底層呼叫Iterator完成操作
。 foreach還可以用來遍歷陣列
。
/**
* jdk 5.0 新增了foreach迴圈(增強for迴圈),用於遍歷集合、陣列
*/
public class ForTest {
@Test
public void test1(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//for(集合中元素的型別 區域性變數 : 集合物件)
//內部仍然呼叫了迭代器。
for(Object obj : coll){
System.out.println(obj);
}
}
@Test
public void test2(){
int[] arr = new int[]{1,2,3,4,5,6};
//for(陣列元素的型別 區域性變數 : 陣列物件)
for(int i : arr){
System.out.println(i);
}
}
//練習題
//使用普通的for迴圈,賦值的都是原來的陣列的元素,
//而使用增強for迴圈,賦值的是新的變數s,相當於把"GG"賦值給新的陣列s
//所以原來的陣列元素保持不變
@Test
public void test3(){
String[] arr = new String[]{"MM","MM","MM"};
// //方式一:普通for迴圈的賦值操作
// for(int i = 0;i < arr.length;i++){
// arr[i] = "GG";
// }
//方式二:增強for迴圈的賦值操作
//使用增強for迴圈,賦值的是新的變數s,相當於把"GG"賦值給新的陣列s
for(String s : arr){
s = "GG";
System.out.println(s);
}
System.out.println("***************");
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
}
}
4.Collection子介面一:List介面
- 鑑於Java中陣列用來儲存資料的侷限性,我們通常使用
List替代陣列
- List集合類中的
元素有序
、且可重複
,集合中的每個元素都有其對應的順序索引
。 - List容器中的元素都對應一個整數型的序號記載其在容器中的位置,可以
根據序號存取容器中的元素
。 - JDK API中
List介面
的實現類
常用的有:ArrayList
、LinkedList
和Vector
。
4.1 List介面常用實現類的對比
/**
* 1. List介面框架
*
* |----Collection介面:單列集合,用來儲存一個一個的物件
* |----List介面:儲存有序的、可重複的資料。 -->“動態”陣列,替換原有的陣列
* |----ArrayList:作為List介面的主要實現類;執行緒不安全的,效率高;底層使用Object[] elementData儲存
* |----LinkedList:對於頻繁的插入、刪除操作,使用此類效率比ArrayList高;底層使用雙向連結串列儲存
* |----Vector:作為List介面的古老實現類;執行緒安全的,效率低;底層使用Object[] elementData儲存
*/
4.2 ArrayList的原始碼分析
ArrayList
是List 介面
的典型實現類
、主要實現類
- 本質上,
ArrayList
是物件引用的一個 “變長”陣列
/**
* 2. ArrayList的原始碼分析:
* 2.1 jdk 7的情況下
* ArrayList list = new ArrayList();//底層建立了長度是10的Object[]陣列elementData
* list.add(123);//elementData[0] = new Integer(123);
* ...
* list.add(11);//如果此次的新增導致底層elementData陣列容量不夠,則需要擴容。
* 預設情況下,擴容為原來容量的1.5倍,同時需要將原有陣列中的資料複製到新的陣列中。
*
* 結論:建議開發中使用帶參的構造器:ArrayList list = new ArrayList(int capacity)
*
* 2.2 jdk 8中ArrayList的變化:
* ArrayList list = new ArrayList();//底層Object[] elementData初始化為{}.並沒有建立長度為10的陣列
*
* list.add(123);//第一次呼叫add()時,底層才建立了長度為10的陣列,並將資料123新增到elementData[0]
* ...
* 後續的新增和擴容操作與jdk 7 無異。
*
* 2.3 小結:jdk7中的ArrayList物件的建立類似於單例的餓漢式,
* 而jdk8中的ArrayList物件的建立類似於單例的懶漢式,延遲了陣列的建立,節省記憶體。
*/
4.3 LinkedList的原始碼分析
- 對於
頻繁的插入或刪除元素的操作
,建議使用LinkedList
類,效率較高 LinkedList
:雙向連結串列
,內部沒有宣告陣列
,而是定義了Node型別的first
和last
,用於記錄首末元素。同時,定義內部類Node
,作為LinkedList中儲存資料的基本結構。
/**
* 3. LinkedList的原始碼分析:
* LinkedList list = new LinkedList(); 內部宣告瞭Node型別的first和last屬性,預設值為null
* list.add(123);//將123封裝到Node中,建立了Node物件。
*
* 其中,Node定義為:體現了LinkedList的雙向連結串列的說法
* private static class Node<E> {
* E item;
* Node<E> next;
* Node<E> prev;
*
* Node(Node<E> prev, E element, Node<E> next) {
* this.item = element;
* this.next = next;
* this.prev = prev;
* }
* }
*
*/
4.4 Vector的原始碼分析
- Vector 是一個
古老的集合
,JDK1.0就有了。大多數操作與ArrayList相同,區別之處在於Vector是執行緒安全的
。 - 在各種list中,
最好把ArrayList作為預設選擇
。當插入、刪除頻繁時,使用LinkedList
;Vector總是比ArrayList慢,所以儘量避免使用。
/**
* 4. Vector的原始碼分析:jdk7和jdk8中通過Vector()構造器建立物件時,
* 底層都建立了長度為10的陣列。在擴容方面,預設擴容為原來陣列長度的2倍。
*/
4.5 List介面中的常用方法測試
List除了從Collection集合繼承的方法外,List 集合裡新增了一些根據索引來操作集合元素的方法。
void add(intindex, Object ele)
: 在index位置插入ele元素boolean addAll(int index, Collection eles)
: 從index位置開始將eles中的所有元素新增進來Object get(int index)
: 獲取指定index位置的元素int indexOf(Object obj)
: 返回obj在集合中首次出現的位置`int lastIndexOf(Object obj)
: 返回obj在當前集合中末次出現的位置Object remove(int index)
: 移除指定index位置的元素,並返回此元素Object set(int index, Object ele)
: 設定指定index位置的元素為eleList subList(int fromIndex, int toIndex)
: 返回從fromIndex到toIndex位置的子集合
/**
* 5. List介面中的常用方法
*/
public class ListTest {
/**
* void add(int index, Object ele):在index位置插入ele元素
* boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素新增進來
* Object get(int index):獲取指定index位置的元素
* int indexOf(Object obj):返回obj在集合中首次出現的位置
* int lastIndexOf(Object obj):返回obj在當前集合中末次出現的位置
* Object remove(int index):移除指定index位置的元素,並返回此元素
* Object set(int index, Object ele):設定指定index位置的元素為ele
* List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的子集合
*
* 總結:常用方法
* 增:add(Object obj),往末尾新增
* 刪:remove(int index) / remove(Object obj)
* 改:set(int index, Object ele)
* 查:get(int index)
* 插:add(int index, Object ele),在指定位置新增
* 長度:size()
* 遍歷:① Iterator迭代器方式
* ② 增強for迴圈
* ③ 普通的迴圈
*/
@Test
public void test3(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
//方式一:Iterator迭代器方式
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("***************");
//方式二:增強for迴圈
for(Object obj : list){
System.out.println(obj);
}
System.out.println("***************");
//方式三:普通for迴圈
for(int i = 0;i < list.size();i++){
System.out.println(list.get(i));
}
}
@Test
public void test2(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom",12));
list.add(456);
//int indexOf(Object obj):返回obj在集合中首次出現的位置。如果不存在,返回-1.
int index = list.indexOf(4567);
System.out.println(index);
//int lastIndexOf(Object obj):返回obj在當前集合中末次(最後一次出現)出現的位置。如果不存在,返回-1.
System.out.println(list.lastIndexOf(456));
//Object remove(int index):移除指定index位置的元素,並返回此元素
Object obj = list.remove(0); //移除第一個元素
System.out.println(obj);
System.out.println(list);
//Object set(int index, Object ele):設定指定index位置的元素為ele
list.set(1,"CC");
System.out.println(list);
//List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的左閉右開區間的子集合
List subList = list.subList(2, 4); //[2,4),左閉右開
System.out.println(subList);
System.out.println(list);
}
@Test
public void test1(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom",12));
list.add(456);
System.out.println(list);
//void add(int index, Object ele):在index位置插入ele元素
list.add(1,"BB");
System.out.println(list);
//boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素新增進來
List list1 = Arrays.asList(1, 2, 3);
list.addAll(list1);
// list.add(list1); //相當於把list1看成一個整體,新增到list集合中
System.out.println(list.size());//9
//Object get(int index):獲取指定index位置的元素
System.out.println(list.get(0)); //獲取第一個位置的元素
}
}
4.6 有關List的面試題
面試題一
請問ArrayList
/ LinkedList
/ Vector
的異同?談談你的理解?ArrayList的底層是什麼
?擴容機制?Vector 和 ArrayList的最大區別
?
/**
* 請問ArrayList/LinkedList/Vector的異同?談談你的理解?
* ArrayList底層是什麼?擴容機制?Vector和ArrayList的最大區別?
*
* ArrayList和LinkedList的異同
* 二者都是執行緒不安全的,相對於執行緒安全的Vector,執行效率高。
* 此外,ArrayList是實現了基於動態陣列的資料結構,LinkedList是基於雙向連結串列的資料結構。
* 對於隨機訪問get和set,ArrayList優於LinkedList,因為LinkedList要移動指標。
* 對於新增操作add(特指插入)和刪除操作remove,LinkedList比較佔優勢,因為ArrayList要移動資料。
*
* ArrayList和Vector的區別
* Vector和ArrayList幾乎是完全相同的,
* 唯一的區別在於Vector是同步類(synchronized),屬於強同步類。
* 因此開銷就比ArrayList要大,訪問要慢。正常情況下,
* 大多數的Java程式設計師使用ArrayList而不是Vector,
* 因為同步完全可以由程式設計師自己來控制。Vector每次擴容請求其大小的2倍空間,
* 而ArrayList是1.5倍。Vector還有一個子類Stack。
*/
面試題二
/**
List面試題
*/
public class ListExer {
/*
區分List中remove(int index)和remove(Object obj)
*/
@Test
public void testListRemove() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
System.out.println("原來的集合元素:" + list);
updateList(list);
System.out.println(list);
}
private void updateList(List list) {
// list.remove(2); //刪除索引是2的元素
list.remove(new Integer(2)); //刪除元素是2的元素
}
}
相關文章
- Java 集合框架------ArrayList原始碼分析Java框架原始碼
- 集合框架原始碼學習之LinkedList框架原始碼
- ArrayList & LinkedList原始碼解析原始碼
- 集合框架原始碼學習之ArrayList框架原始碼
- 3、List集合——ArrayList、LinkedList
- 深入瞭解這些Java框架,看看哪個更適合你?Java框架
- 集合-ArrayList 原始碼解析原始碼
- JAVA集合:LinkedList原始碼解析Java原始碼
- 深入剖析LinkedList原始碼原始碼
- 如果你還不瞭解 Java Class 檔案結構,來看看這篇吧Java
- Java List 常用集合 ArrayList、LinkedList、VectorJava
- List集合(ArrayList-LinkedList);Set集合(HashSet-TreeSet)
- JAVA集合:ArrayList原始碼分析Java原始碼
- 【Java集合】ArrayList原始碼分析Java原始碼
- Java集合之LinkedList原始碼解析Java原始碼
- 集合原始碼分析[3]-ArrayList 原始碼分析原始碼
- Java集合原始碼剖析——ArrayList原始碼剖析Java原始碼
- [原始碼分析]ArrayList和LinkedList如何實現的?我看你還有機會!原始碼
- Java-ArrayList & LinkedList的原始碼對比分析Java原始碼
- Java集合之ArrayList原始碼解析Java原始碼
- java集合原始碼分析(三):ArrayListJava原始碼
- Java 集合系列之 LinkedList原始碼分析Java原始碼
- Java集合原始碼學習(3)LinkedListJava原始碼
- 如果你還不瞭解Java類的載入過程,來看看這一篇吧Java
- 深入瞭解SpringMVC原始碼解析SpringMVC原始碼
- Java集合原始碼學習(2)ArrayListJava原始碼
- JAVA ArrayList集合底層原始碼分析Java原始碼
- List介面下的集合原始碼分析——LinkedList原始碼
- 死磕 java集合之LinkedList原始碼分析Java原始碼
- List集合總結,對比分析ArrayList,Vector,LinkedList
- 深入淺出!阿里P7架構師帶你分析ArrayList集合原始碼,建議是先收藏再看!阿里架構原始碼
- Java集合框架(一)-ArrayListJava框架
- 集合框架2- ArrayList框架
- 還不懂 ConcurrentHashMap ?這份原始碼分析瞭解一下HashMap原始碼
- 死磕 java集合之ArrayList原始碼分析Java原始碼
- Java集合-ArrayList原始碼解析-JDK1.8Java原始碼JDK
- Java類集框架 —— LinkedList原始碼分析Java框架原始碼
- LinkedList詳解-原始碼分析原始碼