集合概述:
集合和數組都可以儲存多個對象,但是數組的長度不可變,集合可以儲存數量變化的資料。java中的集合類主要由兩個接口派生出,Collection和Map
Collection接口和Iterator接口:
概述:Collection接口是List,Set和Queue接口的父接口
Collection中的主要方法如下:
方法名稱 | 方法概述 |
---|---|
boolean add(Object o) | 該方法向集合中添加一個元素,成功傳回true |
boolean addAll(Collection c) | 該方法将集合C中的元素添加到指定集合中,成功傳回true |
void clear() | 清除集合中的元素 |
boolean contains(Object o) | 傳回集合裡是否包含指定元素 |
boolean containAll(Collection c) | 傳回集合中是否包含集合c裡的所有元素 |
boolean isEmpty() | 傳回集合是否為空 |
Iterator iterator() | 傳回一個Iterator對象,用于周遊集合裡的元素 |
boolean remove(Object o) | 删除集合中的指定元素 |
boolean removeAll(Coolection c) | 從指定集合中删除所包含的c集合中的全部元素 |
boolean retailAll(Coolection c) | 從集合中删除集合中不包含的元素 |
int size() | 傳回集合中元素的個數 |
Object[] toArray() | 該方法把集合轉化成一個數組 |
package cn.itcast.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import org.junit.jupiter.api.Test;
public class CollectionTest {
@Test
public void testCollection(){
Collection c=new ArrayList();
c.add("孫悟空");
c.add(6);
System.out.println("c集合的元素個數為"+c.size());
c.remove(6);
System.out.println("c集合的元素個數為"+c.size());
System.out.println("c集合中是否包含孫悟空"+c.contains("孫悟空"));
c.add("javaee實戰");
System.out.println("c集合中的元素"+c);
Collection books=new HashSet();
books.add("瘋狂java講義");
books.add("javaee實戰");
System.out.println("c集合是否完全包含books集合"+c.containsAll(books));
c.removeAll(books);
System.out.println("c集合中的元素"+c);
c.clear();
System.out.println("c集合中的元素"+c);
books.retainAll(c);
System.out.println("books集合中的元素:"+books);
}
@Test
public void IteratorTest() {
Collection<String> c=new ArrayList<String>();
c.add("java程式設計思想");
c.add("瘋狂java講義");
c.add("資料結構與算法");
Iterator it=c.iterator();
while(it.hasNext()) {
String book=(String) it.next();
System.out.println(book);
if(book.equals("瘋狂java講義")) {
it.remove();
}
book="測試字元串";
}
System.out.println(c);
}
}
複制
上述代碼主要展示了Collection的常用方法
testCollection方法的執行結果為:
c集合的元素個數為2
c集合的元素個數為1
c集合中是否包含孫悟空true
c集合中的元素[孫悟空, javaee實戰]
c集合是否完全包含books集合false
c集合中的元素[孫悟空]
c集合中的元素[]
books集合中的元素:[]
複制
IteratorTest方法的執行結果為:
java程式設計思想
瘋狂java講義
資料結構與算法
[java程式設計思想, 資料結構與算法]
複制
Set集合:
概述:Set集合類似于一個罐子,程式可以依次把多個對象裝進這個罐子裡面,Set集合通常不能記住元素的添加順序。Set集合與Collection集合基本相同。
Set三個常用實作類:
HashSet:
概述:
HashSet是Set接口的典型實作,大多數時候使用Set集合時就是使用這個實作類。 HashSet按Hash算法來存儲集合中的元素,是以具有很好的存取和查找性能。
特點:
1、不能保證元素的排列順序,順序可能與添加順序不同,順序也有可能發生變化
2、HashSet不是同步的,如果多個線程同時通路一個 HashSet,假設有兩個或者兩個以上線程同時修改了 HashSet集合時,則必須通過代碼來保證其同步。
3、集合元素值可以是null
存儲資料原理:
HashSet按Hash算法來存儲集合中的元素,HashSet的内部存儲結構是數組加連結清單。
HashSet存儲元素時首先會根據Hash算法計算出元素在記憶體中的位置,然後将資料存放在相應的位置。如果該位置已經存放有元素,那麼接着調用equals方法判斷這兩個元素是否相等,如果相等則是同一個元素,不需要存儲,如果不相等,說明是不同的元素,此時HashSet會在該位置上産生一個連結清單來存儲這兩個元素,此時HashSet的查找性能會降低。
注意點:
在程式中如果重寫某個類的hashCode()方法,則同時也應該修改其equals方法。
hashCode方法的重寫規則:
1、在程式運作過程中,同一個對象多次調用 hashCode()方法應該傳回相同的值。
2、當兩個對象通過 equals方法比較傳回tue時,這兩個對象的 hashCode()方法應傳回相等的值
3、對象中用作 equals方法比較标準的執行個體變量,都應該用于計算 hashCode值。
LinkedHashSet:
概述:
LinkedHashSet是HashSet的子類,它的功能和HashSet類似,LinkedHashSet也是根據元素的hashCode值來存儲,但它同時使用連結清單維護元素的資料,這樣使得元素看起來是以插入的順序儲存的。LinkedHashSet需要使用連結清單維護資料,是以性能方面要比HashSet低一點。
TreeSet:
TreeSet是SortedSet接口的實作類,正如SortedSet的名字所示,TreeSet可以確定元素處于排序狀态。與HashSet相比,TreeSet還有其他幾個方法。
方法名稱 | 方法概述 |
---|---|
Comparator comparator() | 如果 Tree Set采用了定制排序,則該方法傳回定制排序所使用的Comparator;如果 TreeSet采用了自然排序,則傳回nul |
Object first() | 傳回集合中的第一個元素 |
Object last() | 傳回集合中的最後一個元素 |
Object lower(Object e) | 傳回集合中位于指定元素之前的元素(即小于指定元素的最大元素,參考元素不需要是集合中的元素) |
Object higher(Object e) | 傳回集合中位于指定元素之後的元素 |
SortedSet subSet(Object fromElement,Object toElement) | 傳回此Set的子集合,範圍從 fromElement(包含)到 toElement(不包含)。 |
SortedSet headSet(Object toElement) | 傳回此Set的子集,由小于 toLerent的元素組成。 |
SortedSet tailSet(Object fromElement) | 回此Set的子集,由大于或等于 fromElement的元素組成。 |
package cn.itcast.collection;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet nums=new TreeSet();
nums.add(5);
nums.add(2);
nums.add(10);
nums.add(-9);
System.out.println(nums);
System.out.println(nums.first());
System.out.println(nums.last());
System.out.println(nums.headSet(4));
System.out.println(nums.tailSet(5));
System.out.println(nums.subSet(2, 8));
}
}
複制
運作結果:
[-9, 2, 5, 10]
-9
10
[-9, 2]
[5, 10]
[2, 5]
複制
上述代碼展示了TreeSet的常用方法
各個Set集合的性能分析:
1、Hash Set和 TreeSet是Set的兩個典型實作,到底如何選擇 Hash Set和 Tree Set呢? HashSet的性能總是比 TreeSet好(特别是最常用的添加、查詢元素等操作),因為 TreeSet需要額外的紅黑樹算法來維護有Set時,才應該使用 TreeSet,否則都應該使用 HashSet。
2、HashSet還有一個子類:LinkedHash Set,對于普通的插入、删除操作, LinkedHashSet比 HashSet要略微慢一點,這是由維護連結清單所帶來的額外開銷造成的,但由于有了連結清單,周遊 LinkedHashSe會更快。
List集合:
定義:
List集合代表一個元素有序、可重複的集合,集合中每個元素都有其對應的順序索引。List集合允許使用重複元素,可以通過索引來通路指定位置的集合元素。List集合預設按元素的添加順序設定元素的索引,例如第一次添加的元素索引為0,第二次添加的元素索引為1
list集合中特有的方法:
方法名稱 | 方法描述 |
---|---|
void add(int index,Object element) | 将元素element插入到集合的指定位置 |
boolean addAll(int index,Collection c) | 将集合c所包含的所有元素插入到List集合的Index處 |
Object get(int index) | 傳回集合index索引處的元素 |
int indexOf(Object o) | 傳回對象o在List集合中第一次出現的位置索引 |
int lastIndexOf(Object o) | 傳回對象o在List集合中最後一次出現的位置索引 |
Object remove(int index) | 删除并傳回Index索引處的位置 |
Object set(int index,Object element) | 将index索引處的元素替換成element對象,傳回被替換的舊元素。 |
list的基本使用:
List books=new ArrayList();
books.add(new String("輕量級javaee實戰"));
books.add(new String("瘋狂java講義"));
books.add(new String("瘋狂Android講義"));
books.add(new String("瘋狂ios講義"));
books.sort((o1,o2)->((String)o1).length()-((String)o2).length());
System.out.println(books);
books.replaceAll(ele->((String)ele).length());
System.out.println(books);
複制
list的疊代方法:
String[] books = {"輕量級javaee實戰","瘋狂java講義","瘋狂Android講義","瘋狂ios講義"};
List bookList=new ArrayList();
for(int i=0;i<books.length;i++) {
bookList.add(books[i]);
}
ListIterator lit=bookList.listIterator();
while(lit.hasNext()) {
System.out.println(lit.next());
lit.add("------分隔符-----");
}
System.out.println("========下面開始反向疊代======");
while(lit.hasPrevious()) {
System.out.println(lit.previous());
}
複制
ArrayList和Vertor:
定義:
ArrayList和Vertor是list的實作類,list中的方法全部都适用于ArrayList和Vertor。ArrayList和Vertor的底層是用數組實作的,ArrayList或 Vector對象使用 initialCapacity參數來設定該數組的長度,當向 ArrayList或 Vector中添加元素超出了該數組的長度時,它們的 initialCapacity會自動增加。
Queue集合:
Queue用于模拟隊列這種資料結構,隊列是先進先出的資料結構。Queue接口中提供了
queue中的方法:
方法名稱 | 方法描述 |
---|---|
void add(Object e) | 将元素加入到隊列尾部 |
Object element() | 擷取隊列頭部元素,但是不删除 |
Boolean offer(Object e) | 将元素加入到隊列尾部,當使用容量有限的隊列時,此方法比add效果好 |
Object peek() | 擷取頭部元素,但是不删除 |
Object poll() | 擷取頭部元素,并删除該元素 |
Object remove() | 擷取頭部元素,并删除該元素 |
LinkedList:
LinkedList也是List的實作類,它與ArrayList不同,LinkedList的底層是基于連結清單實作。同時,LinkedList還實作了Deque接口,可以被當成雙端隊列來使用,是以既可以被當成“棧”來使用,也可以被當成隊列使用
LinkedList的基本使用:
public class LinkedListTest {
public static void main(String[] args) {
LinkedList books=new LinkedList();
books.offer("瘋狂java講義");
books.push("javaee企業級實戰");
books.offerFirst("瘋狂Android講義");
for(int i=0;i<books.size();i++) {
System.out.println("周遊中--"+books.get(i));
}
System.out.println(books.peekFirst());
System.out.println(books.peekLast());
System.out.println(books.pop());
System.out.println(books);
System.out.println(books.pollLast());
System.out.println(books);
}
}
複制
List集合的性能分析:
- ArrayList底層是數組實作的,查詢速度快,增删速度慢,線程不安全
- Vertor底層是數組實作的,但是Vertor是線程安全的,是以效率較低
- LinkedList的底層是連結清單實作的,增删速度快,查詢速度慢,線程不安全
如果經常做增删操作,則推薦使用LinkedList,如果經常使用查詢操作,則推薦使用ArrayList,如果兩個操作都多,則推薦使用ArrayList