Java自學第6期——Collection、Map、迭代器、泛型、可變引數、集合工具類、集合資料結構、Debug
集合:集合是java中提供的一種容器,可以用來儲存多個數據。
集合和陣列既然都是容器,它們有啥區別呢?
- 陣列的長度是固定的。集合的長度是可變的。
- 陣列中儲存的是同一型別的元素,可以儲存基本資料型別值。集合儲存的都是物件。而且物件的型別可以不一致。
- 在開發中一般當物件多的時候,使用集合進行儲存。
集合按照其儲存結構可以分為兩大類,分別是
單列集合java.util.Collection
和雙列集合java.util.Map
,
綜述:
根接 口 | Collection | Map |
---|---|---|
子介面 | List、Set | 未學 |
實現類 | Vector、LinkedList、ArrayList,HashSet、TreeSet | HashMap |
再子類 | LinkedHashSet | LinkedHashMap |
一、Collection介面
- Collection:單列集合類的根介面,用於儲存一系列符合某種規則的元素,它有兩個重要的子介面,
- 分別是
java.util.List
和java.util.Set
。 - 其中,
List
的特點是元素有序、元素可重複。 Set
的特點是元素無序,而且不可重複。List
介面的主要實現類有java.util.ArrayList
和java.util.LinkedList
,Set
介面的主要實現類有java.util.HashSet
和java.util.TreeSet
。- Collection沒有索引,不能直接遍歷,先轉換成陣列
Collection是所有單列集合的父介面,因此在Collection中定義了單列集合(List和Set)通用的一些方法,
-
這些方法可用於操作所有的單列集合。方法如下:
-
public boolean add(E e)
: 把給定的物件新增到當前集合中 。可以不用接收 -
public void clear()
:清空集合中所有的元素。 -
public boolean remove(E e)
: 把給定的物件在當前集合中刪除。 -
public boolean contains(E e)
: 判斷當前集合中是否包含給定的物件。 -
public boolean isEmpty()
: 判斷當前集合是否為空。 -
public int size()
: 返回集合中元素的個數。 -
public Object[] toArray()
: 把集合中的元素,儲存到陣列中。
public static void main(String[] args) {
//多型,介面指向實現類
//此處ArrayList改成HashSet等其他集合也可以,方法一樣
Collection<String> collection1 = new ArrayList<>();
// Collection<String> collection1 = new HashSet<>();
//列印空,不是地址,說明重寫了toString方法
System.out.println(collection1);
collection1.add("kiana");
//列印[kiana]
System.out.println(collection1);
collection1.add("bronya");
collection1.add("Fuka");
//[kiana, bronya, Fuka]
System.out.println(collection1);
collection1.remove("bronya");
//[kiana, Fuka]
System.out.println(collection1);
//判斷有無元素Mei
boolean criticalResult = collection1.contains("Mei");
//false
System.out.println(criticalResult);
//判斷集合是否為空
boolean Result2 = collection1.isEmpty();
//false
System.out.println(Result2);
int sizeResult = collection1.size();
//2
System.out.println(sizeResult);
//把集合變成陣列
Object[] array = collection1.toArray();
//遍歷陣列,kiana Fuka
for (int i = 0; i <array.length ; i++) {
System.out.println(array[i]);
}
//刪除集合元素,集合本身還在
collection1.clear();
//輸出[]
System.out.println(collection1);
}
二、迭代器
Iterator迭代器,是Collection集合通用的取出元素的方式,先判斷集合有沒有元素,有就取出一個元素,再繼續判斷有沒有元素……直到把集合中所有元素全部取出。這種取出方式稱作迭代。
boolean hasNext():(判斷)如果仍有元素可以迭代,則返回 true。
E next():(取出)返回迭代的下一個元素。
void remove():從迭代器指向的 collection 中移除迭代器返回的最後一個元素(可選操作)。
Iterator是介面 不能直接使用,需要介面的實現類。注意,Iterator介面也是有泛型的,與集合相同。Collection接口裡有個方法:
iterator() ,返回的就是Iterator的實現類物件。
Iterator
public static void main(String[] args) {
Collection<String> collection1 = new ArrayList<>();
collection1.add("板鴨");
collection1.add("芽衣");
//[板鴨, 芽衣]
System.out.println(collection1);
//第一步,獲取這個集合的迭代器。介面指向實現類物件
Iterator<String> iterator = collection1.iterator();
//第二步,判斷有沒有元素
System.out.println(iterator.hasNext());
//第三步,取出元素
String next = iterator.next();
//板鴨
System.out.println(next);
//true
System.out.println(iterator.hasNext());
//芽衣
System.out.println(iterator.next());
//已經沒有元素了,再取會丟擲NoSuchElementException沒有元素異常
// System.out.println(iterator.next());
//優化
Collection<String> collection2 = new ArrayList<>();
collection2.add("板鴨");
collection2.add("芽衣");
Iterator<String> iterator1 = collection2.iterator();
//板鴨芽衣
while(iterator1.hasNext()){
System.out.print(iterator1.next());
}
}
三、泛型
- 泛型:一種未知的資料型別,定義集合時若暫未確定集合內元素型別,可使用泛型。
- 泛型也可以看作是一個變數,用來接收資料型別。
- E e:Element 元素
- T t:Type 型別
- 建立集合物件的時候,就會確認泛型的資料型別
*不使用泛型時,預設Object型別,可以儲存任意型別的資料。壞處:不安全,會引發異常。 - 好處:避免了型別轉換的麻煩;把執行期異常,提升到了編譯期。
public static void main(String[] args) {
method1();
method2();
}
/*
建立集合物件,不使用泛型時,預設Object型別,可以儲存任意型別的資料。
壞處:不安全,會引發異常。
*/
private static void method1(){
ArrayList array1 = new ArrayList();//建立集合
array1.add("女武神");//儲存字串
array1.add(12);//儲存整數
//使用迭代器遍歷
Iterator iterator1 = array1.iterator();
while(iterator1.hasNext()){
Object obj1 = iterator1.next();
System.out.println(obj1);//輸出:女武神 12
//假如要使用String類裡的lenghth()輸出字串長度,
// 需要把Object型別的obj1向下轉型為String型別
String string1 = (String)obj1;
System.out.println(string1.length());//3
//上面產生了ClassCastException型別轉換異常,這就是不使用泛型的缺點
}
}
private static void method2(){
ArrayList<String> list = new ArrayList<>();
list.add("Valkyrie");
Iterator<String> iterator2 = list.iterator();
while(iterator2.hasNext()){
System.out.println(iterator2.next());
}
}
- 定義一個含有泛型的資料型別,模擬ArrayList集合。
- 泛型可以接收任意的資料型別,可以使用Integer,String、Object……
- 建立物件的時候確定泛型的資料型別。
- 不寫泛型預設是Object型別
//新增泛型E:
public class Demo05_class<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
- 測試類
物件類寫成泛型,不把它寫死,要什麼型別就在建立物件的時候定義
*/
public class Demo05_class1 {
public static void main(String[] args) {
//不寫泛型預設是Object型別
Demo05_class obj = new Demo05_class();
obj.setName("字串");
//建立Demo05_class物件,使用Integer泛型
Demo05_class<Integer> obj2 = new Demo05_class<>();
obj2.setName(123);
System.out.println(obj2.getName());
//使用含有泛型的方法
Demo05_method obj3 = new Demo05_method();
//傳遞什麼型別,泛型就是什麼型別
obj3.method1("666");//String
obj3.method1(666);//Integer
//靜態方法通過類名點方法名直接使用。
Demo05_method.method2("666");
//建立介面實現類物件方法1
Demo05_InterfaceImpl obj4 = new Demo05_InterfaceImpl();
obj4.method4("888");
//建立介面實現類物件方法2,在建立物件時確認泛型
Demo05_InterfaceImpl2<String> obj5 = new Demo05_InterfaceImpl2();
obj5.method4("字串");
}
- 定義介面的實現類,指定介面的泛型
public interface Iterator<E>{
E next();
}
public class Demo05_InterfaceImpl implements Demo05_Interface<String> {
@Override
public void method4(String i){
System.out.println(i);
}
}
- 介面和實現類後都寫上泛型, 重寫時泛型作為引數進入方法
public class Demo05_InterfaceImpl2<I> implements Demo05_Interface<I> {
@Override
public void method4(I i){
System.out.println("重寫2");
}
}
- 定義含有泛型的方法:
泛型定義在方法的修飾符和返回值之間,引數列表裡可以通過泛型使用
在呼叫方法的時候確認泛型的使用型別
public class Demo05_method {
public <E> void method1(E one) {
System.out.println(one);
}
//定義一個含有泛型的靜態方法
public static <S> void method2(S s){
System.out.println("含有泛型的靜態方法");
}
}
- 泛型萬用字元<?>在引數傳遞的時候使用
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
list1.add("字串");
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(666);
//該方法能同時呼叫不同型別的集合
method1(list1);//字串
method1(list2);//666
}
//泛型萬用字元在引數傳遞的時候使用
public static void method1(ArrayList<?> list){
Iterator<?> iterator1 = list.iterator();
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
鬥地主案例實現
public static void main(String[] args) {
//定義儲存54張牌的ArrayList集合
ArrayList<String> array1 = new ArrayList<>();
//定義兩個陣列,一個儲存花色,一個儲存序號
String[] colors = {"黑桃","紅桃","方塊","梅花"};
String[] nubers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//集合裡儲存大王小王
array1.add("大王");
array1.add("小王");
//迴圈巢狀兩個陣列,組裝52張牌
for (String numbers:nubers){
for (String colours : colors) {
//System.out.println(colours+numbers);
//把組裝好的牌儲存到集合中
array1.add(colours+numbers);
}
}
// System.out.println(array1);
//洗牌,通過Collections裡的shuffle方法
Collections.shuffle(array1);
// System.out.println(array1);
//定義四個集合,儲存玩家的牌
ArrayList<String> play01 = new ArrayList<>();
ArrayList<String> play02 = new ArrayList<>();
ArrayList<String> play03 = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
//發牌
System.out.println(array1.size());
for (int i = 0; i < array1.size() ; i++) {
//獲取每一張牌
String str1 = array1.get(i);
if ( i>=51){
//底牌
dipai.add(str1);
}else if (i%3==0){
//玩家1發牌
play01.add(str1);
}else if (i%3==1){
//玩家2發牌
play02.add(str1);
}else if (i%3==2){
//玩家3發牌
play03.add(str1);
}
}
//看牌
System.out.println("1號:" + play01);
System.out.println("2號:" + play02);
System.out.println("3號:" + play03);
System.out.println("底牌:"+ dipai);
}
四、List介面
Collection下一個List一個Set。
List集合下的實現類中,ArrayList查詢快,增刪慢;LinkedList是List藉口的連結串列實現,查詢慢,增刪快。
import java.util.List;
- List:有序集合(存取順序相同),有索引,允許儲存重複元素。底層是陣列。此實現是多執行緒,非同步。
- 方法:
boolean add(E e)
向列表的尾部新增指定的元素(可選操作)。
void add(int index, E element)
在列表的指定位置插入指定元素(可選操作)。
E get(int index)
返回列表中指定位置的元素。
ListIteratorlistIterator()
返回此列表元素的列表迭代器(按適當順序)。
ListIteratoristIterator(int index)
返回列表中元素的列表迭代器(按適當順序),從列表的指定位置開始。
E remove(int index)
移除列表中指定位置的元素(可選操作)。
boolean remove(Object o)
從此列表中移除第一次出現的指定元素(如果存在)(可選操作)。
public static void main(String[] args) {
//多型
List<String> list1 = new ArrayList<>();
list1.add("光");
list1.add("翼");
list1.add("展");
list1.add("開");
list1.add(0,"kiana");
System.out.println(list1.get(0));//kiana
ListIterator<String> listIterator1 = list1.listIterator();
ListIterator<String> listIterator2 = list1.listIterator(1);
while(listIterator1.hasNext()){
System.out.println(listIterator1.next());//kiana 光 翼 展 開
}
while(listIterator2.hasNext()){
System.out.println(listIterator2.next());//光翼展開
}
list1.remove(0);
System.out.println(list1);//[光, 翼, 展, 開]
list1.remove("光");
System.out.println(list1);//[翼, 展, 開]
}
實現類LinkedList
- LinkedList集合查詢慢,增刪快,含有大量用於修改首尾的方法。
如果使用LinkedList特有的方法,則不能使用多型 - 方法:
void addFirst(E e):
將指定元素插入此列表的開頭。
void addLast(E e):
將指定元素新增到此列表的結尾。
void clear():
從此列表中移除所有元素。
boolean contains(Object o):
如果此列表包含指定元素,則返回 true。
E get(int index):
返回此列表中指定位置處的元素。
E getFirst():
返回此列表的第一個元素。
E getLast():
返回此列表的最後一個元素。
E removeFirst():
移除並返回此列表的第一個元素。
E removeLast():
移除並返回此列表的最後一個元素。
public static void main(String[] args) {
LinkedList<String> list1 = new LinkedList<>();
list1.add("kiana");
list1.addFirst("love");
list1.addLast("is me");
System.out.println(list1);//[love, kiana, is me]
System.out.println(list1.get(1));//kiana
if (list1.contains("love")){
System.out.println("含有lova");
}
list1.removeFirst();
System.out.println(list1);//[kiana, is me]
}
- Vector集合,實現可增長的物件陣列,底層是陣列,已經被ArrayList取代,單執行緒
五、Set介面
Collection的另一個孩子,
1.不能儲存重複元素。
2.沒有索引,不能使用普通的for迴圈遍歷。
3.底層是雜湊表結構,查詢速度很快,存取元素順序可能不一致。
4.HashSet集合類實現Set介面;
- 方法:
boolean add(E e):
如果 set 中尚未存在指定的元素,則新增此元素(可選操作)。
boolean addAll(Collection<? extends E> c):
如果 set 中沒有指定 collection 中的所有元素,則將其新增到此 set 中(可選操作)。
void clear():
移除此 set 中的所有元素(可選操作)。
boolean contains(Object o):
如果 set 包含指定的元素,則返回 true。
boolean containsAll(Collection<?> c):
如果此 set 包含指定 collection 的所有元素,則返回 true。
boolean equals(Object o):
比較指定物件與此 set 的相等性。
int hashCode():
返回 set 的雜湊碼值。
boolean isEmpty():
如果 set 不包含元素,則返回 true。
Iteratoriterator():
返回在此 set 中的元素上進行迭代的迭代器。
boolean remove(Object o):
如果 set 中存在指定的元素,則將其移除(可選操作)。
boolean removeAll(Collection<?> c):
移除 set 中那些包含在指定 collection 中的元素(可選操作)。
boolean retainAll(Collection<?> c):
僅保留 set 中那些包含在指定 collection 中的元素(可選操作)。
int size():
返回 set 中的元素數(其容量)。
Object[] toArray():
返回一個包含 set 中所有元素的陣列。
T[] toArray(T[] a):
返回一個包含此 set 中所有元素的陣列;返回陣列的執行時型別是指定陣列的型別。
public static void main(String[] args) {
Set<String> setList1 = new HashSet<>();
setList1.add("Mei");
setList1.add("逐火之蛾");
setList1.add("Mei");//重複元素儲存失敗
System.out.println(setList1.contains("Mei"));
Iterator<String> iterator1 = setList1.iterator();
while (iterator1.hasNext()){
System.out.println(iterator1.next());
}
System.out.println(setList1.size());
HashSet實現類
- 雜湊值是一個十進位制的整數,由系統隨機給出。
Object類的hashCode方法返回物件的雜湊碼值:
int hashCode()
jdk1.8之後,雜湊表=陣列+紅黑樹(加快查詢速度)
儲存資料到集合中,首先計算元素的雜湊值 - 沒有重寫時,HashSet比較的是兩個物件的地址值,
儲存自定義型別的元素時必須重寫hashCode和equals方法同時比較元素和雜湊值更穩妥。
按Alt+Insert重寫方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Demo11_Hash that = (Demo11_Hash) o;
return Objects.equals(name, that.name) &&
Objects.equals(age, that.age);
}
@Override
public int hashCode() {
return super.hashCode();
}
LinkedHashSet(繼承HashSet)
- 具有可預知迭代順序的Set介面的雜湊表和連結串列實現
LinkedHashSet集合extends了HashSet集合,
LinkedHashSet集合底層是雜湊表(連結串列+陣列/紅黑樹)+連結串列,多的連結串列用來記錄元素儲存順序,保證元素有序
public static void main(String[] args) {
HashSet<String> set1 = new HashSet<>();
set1.add("a");
set1.add("a");
set1.add("c");
set1.add("b");
System.out.println(set1);//[a, b, c],無重複,無順序
LinkedHashSet<String> linkedset2 = new LinkedHashSet<>();
linkedset2.add("a");
linkedset2.add("a");
linkedset2.add("c");
linkedset2.add("b");
System.out.println(linkedset2);//[a, c, b],有順序,無重複
}
六、可變引數
- 可變引數:當方法的引數列表資料型別已經確定,但引數的資料型別不確定,就可以使用可變引數
使用格式:定義方法時使用
修飾符 返回值型別 方法名(資料型別...變數名){}
原理:可變引數底層是陣列,根據傳遞引數個數不同,會建立不同長度的陣列,來儲存這些引數。
傳遞的引數個數可以是0個(不傳遞),1,2,3...很多個。
可變引數的終極寫法:
(Object...obj) - 注意:
一個方法的引數列表,只能有一個可變引數。
如果方法的引數有多個,那麼可變引數必須寫在引數列表的末尾。
public static void main(String[] args) {
Sum1();
System.out.println(Sum2(222,111,223,3));//559
Sum3(33,"w",3.14);
}
//定義一個方法,計算兩個int整數的和
public static void Sum1(){
System.out.println("請輸入倆數字");
Scanner num1 = new Scanner(System.in);
Scanner num2 = new Scanner(System.in);
int sum = num1.nextInt()+num2.nextInt();
System.out.println(sum);
}
//計算未定數目的引數的和
public static int Sum2(int...num3){
int Sum= 0;
for (int i : num3) {
Sum += i;
}
return Sum;
}
public static void Sum3(Object...obj){
for (Object o : obj) {
System.out.println(o);
}
}
七、Collections工具類
Collections工具類:java.utils.Collections
- 方法:
public staticboolean addAll(Collection c,T...elements)
往集合中新增多個元素
public static void shuffle(Listlist)
打亂集合順序
public staticvoid sort(List list)
將集合中的元素按照預設順序排序
public staticvoid sort(List list,Comparator <? super T>)
將集合中的元素按照指定規則排序 - 注:被排序的集合裡的元素,必須實現Comparable介面,重寫介面中的compareTo定義排序的規則
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
//addAll
Collections.addAll(list1,"k","i","a","n","a");
System.out.println("addAll:"+list1);
//shuffle
Collections.shuffle(list1);
System.out.println("打亂後:"+list1);
//sort預設(數字預設大小升序,字串預設自然升序abcdefg...)
Collections.sort(list1);
System.out.println("預設排序後:"+list1);//[a, a, i, k, n]
//sort指定,重寫排序規則
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(3);
list2.add(2);
Collections.sort(list2, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//o1-o2代表升序,o2-o1代表降序
return o1-o2;
}
});
System.out.println(list2);//1,2,3
//自定義型別Demo00_Person的排列
ArrayList<Demo00_Person> list3 = new ArrayList<>();
list3.add(new Demo00_Person("琪亞娜",17));
list3.add(new Demo00_Person("芽衣",18));
list3.add(new Demo00_Person("板鴨",15));
list3.add(new Demo00_Person("艦長",20));
System.out.println("自定義型別排列前:"+list3);
Collections.sort(list3, new Comparator<Demo00_Person>() {
@Override
public int compare(Demo00_Person o1, Demo00_Person o2) {
//先按年齡排列
int result = o1.getAge() - o2.getAge();
//如果年齡相同,按照名字排列
if(result == 0){
result = o1.getName().charAt(0)-o2.getName().charAt(0);
}
return result;
}
});
System.out.println("自定義型別排列後:"+list3);
八、集合資料結構
和集合相關的資料結構:棧、佇列,陣列,連結串列,紅黑樹。
- 棧:先進後出
元素儲存到集合中時,先儲存的元素在棧的底部,後進入的元素在棧的頂部,
取出元素時,先取出棧頂部的元素,棧底部的元素後取出。棧的出口和入口相同。
例如:入棧順序123,出棧的順序即為321。
- 佇列:先進先出
入口和出口不同,先入者接近出口,後入者離出口較遠。
- 陣列:查詢快,增刪慢。
查詢快:陣列的地址是連續的,通過首地址找到陣列,再通過索引找到想要的陣列元素。
增刪慢:陣列的長度是固定的,增刪陣列需要建立一個新的陣列,並將源陣列的資料複製到新陣列中。
源陣列在記憶體中被銷燬(垃圾回收)。
- 連結串列(linked list):由一系列節點node(連結串列中的元素)組成,節點在執行時動態生成。
每個節點包含一個儲存資料元素的資料域,和兩個分別儲存自己和下一個節點地址的指標域。
連結串列結構通常有單向連結串列和雙向連結串列。多個節點間通過地址相連。 - 單向連結串列:連結串列中只有一條鏈子,不能保證元素的順序。儲存、取出的資料可能不一致。
- 雙向連結串列:有兩條鏈子,其中一條專門記錄元素的順序,所是一個有序的集合.
查詢慢:想查詢某個元素,需要通過連線的節點,一次向後查詢指定元素。地址不連續,每次查詢需要從頭開始。
增刪快:增刪元素對連結串列整體結構沒有影響,所以快。
- 紅黑樹:
二叉樹:分支不能超過兩格的樹
排序樹/查詢樹:在二叉樹的基礎上,元素是有大小的,左子樹小,右子樹大
紅黑樹:節點紅色或黑色,根節點黑色,葉子節點黑色,每個紅色的節點的子節點都是黑色,任何節點到其
每一個葉子節點的所有路徑上黑色節點的數量是相同的。
九、Map集合介面
java裡集合除了Collections(List/Set)外就是Map集合,用來存放對映關係的物件。
- Collection中的集合,元素是孤立存在的(理解為單身),向集合中儲存元素採用一個個元素的方式儲存。
- Map 中的集合,元素是成對存在的(理解為夫妻)。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的值。
- Collection 中的集合稱為單列集合, Map 中的集合稱為雙列集合。
需要注意的是, Map 中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值。 - java.util.Map<k,v> :key鍵,value值,通過key可以找到對應的value,
value可以重複,一個key對應一個value,key不可以重複。
key和map資料型別可以相同可以不同,
靠key維護他們之間的關係。
HashMap:
Map的兩個常用子類:HashMap和LinkedHashMap
- HashMap:儲存資料採用的雜湊表結構,元素的存取順序不能保證一致。
由於要保證鍵的唯一、不重複,需 要重寫鍵的hashCode()方法、equals()方法。 - LinkedHashMap:HashMap下有個子類LinkedHashMap,儲存資料採用的雜湊表結構+連結串列結構。
通過連結串列結構可以保證元素的存取順序一致;通過雜湊表結構可以保證的鍵的唯一、不重複,
需要重寫鍵的 hashCode()方法、equals()方法。
tips:Map介面中的集合都有兩個泛型變數,在使用時,要為兩個泛型變數賦予資料型別。
兩個泛型變數的數 據型別可以相同,也可以不同。
tips:Map集合不能直接使用迭代器或者foreach進行遍歷。但是轉成Set之後就可以使用了。
Map介面中定義了很多方法,常用的如下:
public V put(K key, V value) : 把指定的鍵與指定的值新增到Map集合中。
public V remove(Object key) : 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
public V get(Object key) 根據指定的鍵,在Map集合中獲取對應的值。
public Set
public Set<Map.Entry<K,V>> entrySet() : 獲取到Map集合中所有的鍵值對物件的集合(Set集合)。
public static void main(String[] args) {
HashMap<Integer,String> list1 = new HashMap<>();
list1.put(0,"kiana");
list1.put(1,"love");
list1.put(2,"me");
//kiana
System.out.println(list1.get(0));
boolean b = list1.containsKey(5);
//false
System.out.println(b);
//遍歷Map集合,先取出key到set集合,再用Iterator或者增強for
Set<Integer> setlist1 = list1.keySet();
Iterator<Integer> iterator = setlist1.iterator();
while (iterator.hasNext()){
Integer key = iterator.next();
String value = list1.get(key);
System.out.println(key+" 對應 "+value);
}
for (Integer key1 : setlist1){
//此處setList1可以直接寫List1.keySet簡化一步
System.out.println(list1.get(key1));
}
Entry:
Map 中存放的是兩種物件,一種稱為key(鍵),一種稱為value(值),
它們在在 Map 中是一一對應關係,這一對物件又稱做 Map 中的一個 Entry(項)
Entry 將鍵值對的對應關係封裝成了物件。
即鍵值對物件,這樣我們在
遍歷 Map 集合時,就可以從每一個鍵值對( Entry )物件中獲取對應的鍵與對應的值。
既然Entry表示了一對鍵和值,那麼也同樣提供了
- 獲取對應鍵和對應值的方法:
public K getKey() :獲取Entry物件中的鍵。
public V getValue() :獲取Entry物件中的值。
在Map集合中也提供了 - 獲取所有Entry物件的方法:
public Set<Map.Entry<K,V>> entrySet() : 獲取到Map集合中所有的鍵值對物件的集合(Set集合)。
public static void main(String[] args) {
HashMap<Integer,String> list2 = new HashMap<>();
//新增三個entry物件
list2.put(1,"1");
list2.put(2,"2");
list2.put(3,"3");
//獲取entry物件到set集合中
Set<Map.Entry<Integer, String>> obj1 = list2.entrySet();
//增強for遍歷set集合,集合裡通過getKey、getValue方法活動物件的鍵值
for (Map.Entry<Integer, String> integerStringEntry : obj1) {
Integer key = integerStringEntry.getKey();
String value = integerStringEntry.getValue();
System.out.println(key+value);//11,22,33
}
- Map集合儲存自定義型別的方法:
當給HashMap中存放自定義物件時,
如果自定義物件作為key存在,
這時要保證物件唯一,必須複寫物件的 hashCode和equals方法.
如果要保證map中存放的key和取出的順序一致,可以使用 java.util.LinkedHashMap 集合來存放。
public static void main(String[] args) {
//key寫為自定義型別
HashMap<Dem00_Person,String> map1 = new HashMap<>();
//建立自定義物件為引數:
map1.put(new Dem00_Person("Kiana",16),"大老婆");
map1.put(new Dem00_Person("Mei",17),"二老婆");
map1.put(new Dem00_Person("Bronya",14),"三老婆");
map1.put(new Dem00_Person("Teresa",12),"小老婆");
//取出元素,鍵找值方式,注意Set型別寫法
Set<Map.Entry<Dem00_Person,String>> obj2 = map1.entrySet();
集合工廠方法 of():
- JDK9對集合新增元素的優化:
通常,我們在程式碼中建立一個集合(例如,List 或 Set ),並直接用一些元素填充它。
例項化集合,幾個 add方法 呼叫,程式碼顯得重複。
Java 9,添加了幾種集合工廠方法,更方便建立少量元素的集合、map例項。
新的List、Set、Map的靜態工廠方法of可以更方便地建立集合的不可變例項。 - 使用前提:
1.集合中元素的數確定且不再改變
2.只適用於List、Set、Map介面,不適用於它們的實現類;
3.Set和Map存的元素不能有重複,List可以
public static void main(String[] args) {
List<String> list1 = List.of("k","i","a","n","a","a");
// list1.add("aa");
// UnsupportedOperationException不支援操作異常,of返回的集合不可再改變
// Set<String> set1 = Set.of("a", "a");
// Set集合儲存重複元素,丟擲IllegalArgumentException非法引數異常
}
十、Debug
IDEA中:
左邊設定斷點,右鍵選擇Debug執行程式,程式停止在了斷點行不再執行
Debug後,下方按鈕從左到右:
- Console:切換到控制檯
- Step Over(F8):程式碼向下執行一行
- Step Into(F7):進入要呼叫的方法
- Step Out(shift + F8):跳出方法
左邊: - Resume Program(F9):調到下一個斷點
- Stop(Ctrl+F2):停止除錯的程式,退出Debug模式