0基礎學java-day14-(集合)

一、集合

前面我們保存多個數據使用的是數組,那么數組有不足的地方,我們分析一下

1.數組

2 集合?

  • 數據類型也可以不一樣?

3.集合的框架體系?

  • Java 的集合類很多,主要分為兩大類,如圖 :[背下來]

?

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;/*** @author 林然* @version 1.0*/
public class Collection_ {public static void main(String[] args) {//1. 集合主要是兩組(單列集合 , 雙列集合)//2. Collection 接口有兩個重要的子接口 List 和Set , 他們的實現子類都是單列集合//3. Map 接口的實現子類 是雙列集合,存放的 K-V//4. 把老師梳理的兩張圖記住ArrayList arrayList =new ArrayList();arrayList.add("jack");arrayList.add("tom");HashMap hashMap =new HashMap();hashMap.put("No1","北京");}
}

4.Collection 接口和常用方法

4.1Collection 接口實現類的特點

  • Collection 接口常用方法,以實現子類 ArrayList 來演示?

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class CollectionMethod {@SuppressWarnings("all")public static void main(String[] args) {List list =new ArrayList();// add:添加單個元素list.add("jack");list.add(10);//這里相當于自動裝箱了,添加的實際是對象list.add(true);System.out.println("list="+list);// remove:刪除指定元素
//list.remove(0);//刪除第一個元素list.remove(true);//指定刪除某個元素System.out.println("list=" + list);// contains:查找元素是否存在System.out.println(list.contains("jack"));//T// size:獲取元素個數System.out.println(list.size());//2// isEmpty:判斷是否為空System.out.println(list.isEmpty());//F// clear:清空list.clear();System.out.println("list=" + list);// addAll:添加多個元素ArrayList list2=new ArrayList();list2.add("加油");list2.add("java大神");list.addAll(list2);System.out.println("list=" + list);// containsAll:查找多個元素是否都存在System.out.println(list.containsAll(list2));//T// removeAll:刪除多個元素list.add("聊齋");list.removeAll(list2);System.out.println("list=" + list);//[聊齋]}
}

4.2 Collection 接口遍歷元素方式 1-使用 Iterator(迭代器)

?

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class CollectionIterator {public static void main(String[] args) {Collection col = new ArrayList();col.add(new Book1("三國演義", "羅貫中", 10.1));col.add(new Book1("小李飛刀", "古龍", 5.1));col.add(new Book1("紅樓夢", "曹雪芹", 34.6));//現在老師希望能夠遍歷 col 集合//1. 先得到 col 對應的 迭代器Iterator iterator =col.iterator();//2. 使用 while 循環遍歷// while (iterator.hasNext()) {//判斷是否還有數據// //返回下一個元素,類型是 Object// Object obj = iterator.next();// System.out.println("obj=" + obj);// }//教大家一個快捷鍵,快速生成 while => itit//顯示所有的快捷鍵的的快捷鍵 ctrl + jwhile (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}//3. 當退出 while 循環后 , 這時 iterator 迭代器,指向最后的元素// iterator.next();//NoSuchElementException//4. 如果希望再次遍歷,需要重置我們的迭代器iterator = col.iterator();System.out.println("===第二次遍歷===");while (iterator.hasNext()) {Object obj = iterator.next();System.out.println("obj=" + obj);}}
}
@SuppressWarnings({"all"})
class Book1 {private String name;private String author;private double price;public Book1(String name, String author, double price) {this.name = name;this.author = author;this.price = price;}@Overridepublic String toString() {return "Book1{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +'}';}
}

4.3 Collection 接口遍歷對象方式 2-for 循環增強

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;/*** @author 林然* @version 1.0*/
public class CollectionFor {@SuppressWarnings("all")public static void main(String[] args) {Collection col = new ArrayList();col.add(new Book1("三國演義", "羅貫中", 10.1));col.add(new Book1("小李飛刀", "古龍", 5.1));col.add(new Book1("紅樓夢", "曹雪芹", 34.6));//使用增強for循環for(Object k:col){System.out.println("book="+k);}}}

?4.4?課堂練習

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class CollectionExercise {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add(new Dog("小黑", 3));list.add(new Dog("大黃", 100));list.add(new Dog("大壯", 8));//先使用for增強for (Object dog : list) {System.out.println("dog=" + dog);}//使用迭代器System.out.println("===使用迭代器來遍歷===");Iterator iterator = list.iterator();while (iterator.hasNext()) {Object dog =  iterator.next();System.out.println("dog=" + dog);}}
}
/*** 創建  3個 Dog {name, age}  對象,放入到 ArrayList 中,賦給 List 引用* 用迭代器和增強for循環兩種方式來遍歷* 重寫Dog 的toString方法, 輸出name和age*/
class Dog {private String name;private int age;public Dog(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;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}

?二、List?

1.List 接口和常用方法?

1.1??List 接口基本介紹

package com.hspedu.list_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class List_ {@SuppressWarnings("all")public static void main(String[] args) {//1. List 集合類中元素有序(即添加順序和取出順序一致)、且可重復 [案例]List list = new ArrayList();list.add("jack");list.add("tom");list.add("mary");list.add("lsl");list.add("tom");System.out.println("list=" + list);
//2. List 集合中的每個元素都有其對應的順序索引,即支持索引
// 索引是從 0 開始的System.out.println(list.get(3));//lsl
//3}
}

?1.2 List 接口的常用方法

package com.hspedu.list_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class ListMethod {@SuppressWarnings("all")public static void main(String[] args) {List list =new ArrayList();list.add("張三豐");list.add("賈寶玉");
// void add(int index, Object ele):在 index 位置插入 ele 元素//在 index = 1 的位置插入一個對象list.add(1, "林然");System.out.println("list=" + list);// boolean addAll(int index, Collection eles):從 index 位置開始將 eles 中的所有元素添加進來List list2 = new ArrayList();list2.add("jack");list2.add("tom");list.addAll(1, list2);System.out.println("list=" + list);// Object get(int index):獲取指定 index 位置的元素// int indexOf(Object obj):返回 obj 在集合中首次出現的位置System.out.println(list.indexOf("tom"));//2// int lastIndexOf(Object obj):返回 obj 在當前集合中末次出現的位置list.add("林然");System.out.println("list=" + list);System.out.println(list.lastIndexOf("林然"));// Object remove(int index):移除指定 index 位置的元素,并返回此元素list.remove(0);System.out.println("list=" + list);// Object set(int index, Object ele):設置指定 index 位置的元素為 ele , 相當于是替換. list.set(1, "瑪麗");System.out.println("list=" + list);// List subList(int fromIndex, int toIndex):返回從 fromIndex 到 toIndex 位置的子集合
// 注意返回的子集合 fromIndex <= subList < toIndexList returnlist = list.subList(0, 2);System.out.println("returnlist=" + returnlist);}
}

?1.3?List 接口課堂練習

package com.hspedu.list_;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class ListExercise {@SuppressWarnings({"all"})public static void main(String[] args) {/*添加10個以上的元素(比如String "hello" ),在2號位插入一個元素"韓順平教育",獲得第5個元素,刪除第6個元素,修改第7個元素,在使用迭代器遍歷集合,要求:使用List的實現類ArrayList完成。*/List list = new ArrayList();for (int i = 0; i < 12; i++) {list.add("hello" + i);}System.out.println("list=" + list);//在2號位插入一個元素"韓順平教育"list.add(1, "韓順平教育");System.out.println("list=" + list);//獲得第5個元素System.out.println("第五個元素=" + list.get(4));//刪除第6個元素list.remove(5);System.out.println("list=" + list);//修改第7個元素list.set(6, "三國演義");System.out.println("list=" + list);//在使用迭代器遍歷集合Iterator iterator = list.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println("obj=" + obj);}}
}

?1.4?List 的三種遍歷方式 [ArrayList, LinkedList,Vector]

package com.hspedu.list_;import java.util.*;public class ListFor {@SuppressWarnings({"all"})public static void main(String[] args) {//List 接口的實現子類 Vector LinkedList//List list = new ArrayList();//List list = new Vector();List list = new LinkedList();list.add("jack");list.add("tom");list.add("魚香肉絲");list.add("北京烤鴨子");//遍歷//1. 迭代器Iterator iterator = list.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println(obj);}System.out.println("=====增強for=====");//2. 增強forfor (Object o : list) {System.out.println("o=" + o);}System.out.println("=====普通for====");//3. 使用普通forfor (int i = 0; i < list.size(); i++) {System.out.println("對象=" + list.get(i));}}
}

?1.5?實現類的課堂練習 2

package com.hspedu.list_;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;@SuppressWarnings({"all"})
public class ListExercise02 {public static void main(String[] args) {//List list = new ArrayList();List list = new LinkedList();//List list = new Vector();list.add(new Book("紅樓夢", "曹雪芹", 100));list.add(new Book("西游記", "吳承恩", 10));list.add(new Book("水滸傳", "施耐庵", 19));list.add(new Book("三國", "羅貫中", 80));//list.add(new Book("西游記", "吳承恩", 10));//如何對集合進行排序//遍歷for (Object o : list) {System.out.println(o);}//冒泡排序sort(list);System.out.println("==排序后==");for (Object o : list) {System.out.println(o);}}//靜態方法//價格要求是從小到大public static void sort(List list) {int listSize = list.size();for (int i = 0; i < listSize - 1; i++) {for (int j = 0; j < listSize - 1 - i; j++) {//取出對象BookBook book1 = (Book) list.get(j);Book book2 = (Book) list.get(j + 1);if (book1.getPrice() > book2.getPrice()) {//交換list.set(j, book2);list.set(j + 1, book1);}}}}
}

package com.hspedu.list_;public class Book {private String name;private String author;private double price;public Book(String name, String author, double price) {this.name = name;this.author = author;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "名稱:" + name + "\t\t價格:" + price + "\t\t作者:" + author;}
}

2.ArrayList 底層結構和源碼分析

2.1?ArrayList 的注意事項

2.2?ArrayList 的底層操作機制源碼分析(重點,難點.)?

?3.Vector 底層結構和源碼剖析

3.1?Vector 的基本介紹

3.2?Vector ArrayList 的比較?

4.LinkedList 底層結構?

4.1?LinkedList 的全面說明

4.2?LinkedList 的底層操作機制?

【這里其實就是涉及數據結構的知識點】

package com.hspedu.list_;public class LinkedList01 {public static void main(String[] args) {//模擬一個簡單的雙向鏈表Node jack = new Node("jack");Node tom = new Node("tom");Node hsp = new Node("老韓");//連接三個結點,形成雙向鏈表//jack -> tom -> hspjack.next = tom;tom.next = hsp;//hsp -> tom -> jackhsp.pre = tom;tom.pre = jack;Node first = jack;//讓first引用指向jack,就是雙向鏈表的頭結點Node last = hsp; //讓last引用指向hsp,就是雙向鏈表的尾結點//演示,從頭到尾進行遍歷System.out.println("===從頭到尾進行遍歷===");while (true) {if(first == null) {break;}//輸出first 信息System.out.println(first);first = first.next;}//演示,從尾到頭的遍歷System.out.println("====從尾到頭的遍歷====");while (true) {if(last == null) {break;}//輸出last 信息System.out.println(last);last = last.pre;}//演示鏈表的添加對象/數據,是多么的方便//要求,是在 tom --------- 老韓直接,插入一個對象 smith//1. 先創建一個 Node 結點,name 就是 smithNode smith = new Node("smith");//下面就把 smith 加入到雙向鏈表了smith.next = hsp;smith.pre = tom;hsp.pre = smith;tom.next = smith;//讓first 再次指向jackfirst = jack;//讓first引用指向jack,就是雙向鏈表的頭結點System.out.println("===從頭到尾進行遍歷===");while (true) {if(first == null) {break;}//輸出first 信息System.out.println(first);first = first.next;}last = hsp; //讓last 重新指向最后一個結點//演示,從尾到頭的遍歷System.out.println("====從尾到頭的遍歷====");while (true) {if(last == null) {break;}//輸出last 信息System.out.println(last);last = last.pre;}}
}//定義一個Node 類,Node 對象 表示雙向鏈表的一個結點
class Node {public Object item; //真正存放數據public Node next; //指向后一個結點public Node pre; //指向前一個結點public Node(Object name) {this.item = name;}public String toString() {return "Node name=" + item;}
}

?4.3?LinkedList 的增刪改查案例

package com.hspedu.list_;import java.util.Iterator;
import java.util.LinkedList;/*** @author 韓順平* @version 1.0*/
@SuppressWarnings({"all"})
public class LinkedListCRUD {public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add(1);linkedList.add(2);linkedList.add(3);System.out.println("linkedList=" + linkedList);//演示一個刪除結點的linkedList.remove(); // 這里默認刪除的是第一個結點//linkedList.remove(2);System.out.println("linkedList=" + linkedList);//修改某個結點對象linkedList.set(1, 999);System.out.println("linkedList=" + linkedList);//得到某個結點對象//get(1) 是得到雙向鏈表的第二個對象Object o = linkedList.get(1);System.out.println(o);//999//因為LinkedList 是 實現了List接口, 遍歷方式System.out.println("===LinkeList遍歷迭代器====");Iterator iterator = linkedList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println("next=" + next);}System.out.println("===LinkeList遍歷增強for====");for (Object o1 : linkedList) {System.out.println("o1=" + o1);}System.out.println("===LinkeList遍歷普通for====");for (int i = 0; i < linkedList.size(); i++) {System.out.println(linkedList.get(i));}//老韓源碼閱讀./* 1. LinkedList linkedList = new LinkedList();public LinkedList() {}2. 這時 linkeList 的屬性 first = null  last = null3. 執行 添加public boolean add(E e) {linkLast(e);return true;}4.將新的結點,加入到雙向鏈表的最后void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}*//*老韓讀源碼 linkedList.remove(); // 這里默認刪除的是第一個結點1. 執行 removeFirstpublic E remove() {return removeFirst();}2. 執行public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}3. 執行 unlinkFirst, 將 f 指向的雙向鏈表的第一個結點拿掉private E unlinkFirst(Node<E> f) {// assert f == first && f != null;final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GCfirst = next;if (next == null)last = null;elsenext.prev = null;size--;modCount++;return element;}*/}
}

4.4?ArrayList LinkedList 比較

三、Set?

1.Set 接口和常用方法?

1.1?Set 接口基本介紹

1.2?Set 接口的常用方法?

List 接口一樣 , Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一樣

1.3?Set 接口的遍歷方式

1.4?Set 接口的常用方法舉例?

package com.hspedu.set_;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;@SuppressWarnings({"all"})
public class SetMethod {public static void main(String[] args) {//老韓解讀//1. 以Set 接口的實現類 HashSet 來講解Set 接口的方法//2. set 接口的實現類的對象(Set接口對象), 不能存放重復的元素, 可以添加一個null//3. set 接口對象存放數據是無序(即添加的順序和取出的順序不一致)//4. 注意:取出的順序的順序雖然不是添加的順序,但是他的固定【就是每次得到的順序的固定的】.Set set = new HashSet();set.add("john");set.add("lucy");set.add("john");//重復,由于重復,只會有一個set.add("jack");set.add("hsp");set.add("mary");set.add(null);//set.add(null);//再次添加null,由于重復,只會有一個for(int i = 0; i <10;i ++) {System.out.println("set=" + set);}//遍歷//方式1: 使用迭代器System.out.println("=====使用迭代器====");Iterator iterator = set.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println("obj=" + obj);}set.remove(null);//方式2: 增強forSystem.out.println("=====增強for====");for (Object o : set) {System.out.println("o=" + o);}//set 接口對象,不能通過索引來獲取}
}

2.HashSet

2.1?HashSet 的全面說明

package com.hspedu.set_;import java.util.HashSet;
import java.util.Set;@SuppressWarnings({"all"})
public class HashSet_ {public static void main(String[] args) {//老韓解讀//1. 構造器走的源碼/*public HashSet() {map = new HashMap<>();}2. HashSet 可以存放null ,但是只能有一個null,即元素不能重復*/Set hashSet = new HashSet();hashSet.add(null);hashSet.add(null);System.out.println("hashSet=" + hashSet);}
}

?2.2?HashSet 案例說明

package com.hspedu.set_;import java.util.HashSet;@SuppressWarnings({"all"})
public class HashSet01 {public static void main(String[] args) {HashSet set = new HashSet();//說明//1. 在執行add方法后,會返回一個boolean值//2. 如果添加成功,返回 true, 否則返回false//3. 可以通過 remove 指定刪除哪個對象System.out.println(set.add("john"));//TSystem.out.println(set.add("lucy"));//TSystem.out.println(set.add("john"));//FSystem.out.println(set.add("jack"));//TSystem.out.println(set.add("Rose"));//Tset.remove("john");System.out.println("set=" + set);//3個//set  = new HashSet();System.out.println("set=" + set);//0//4 Hashset 不能添加相同的元素/數據?set.add("lucy");//添加成功set.add("lucy");//加入不了set.add(new Dog("tom"));//OKset.add(new Dog("tom"));//OkSystem.out.println("set=" + set);//在加深一下. 非常經典的面試題.//看源碼,做分析, 先給小伙伴留一個坑,以后講完源碼,你就了然//去看他的源碼,即 add 到底發生了什么?=> 底層機制.set.add(new String("hsp"));//okset.add(new String("hsp"));//加入不了.System.out.println("set=" + set);}
}
class Dog { //定義了Dog類private String name;public Dog(String name) {this.name = name;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +'}';}
}

?2.3?HashSet 底層機制說明

package com.hspedu.set_;@SuppressWarnings({"all"})
public class HashSetStructure {public static void main(String[] args) {//模擬一個HashSet的底層 (HashMap 的底層結構)//1. 創建一個數組,數組的類型是 Node[]//2. 有些人,直接把 Node[] 數組稱為 表Node[] table = new Node[16];//3. 創建結點Node john = new Node("john", null);table[2] = john;Node jack = new Node("jack", null);john.next = jack;// 將jack 結點掛載到johnNode rose = new Node("Rose", null);jack.next = rose;// 將rose 結點掛載到jackNode lucy = new Node("lucy", null);table[3] = lucy; // 把lucy 放到 table表的索引為3的位置.System.out.println("table=" + table);}
}
class Node { //結點, 存儲數據, 可以指向下一個結點,從而形成鏈表Object item; //存放數據Node next; // 指向下一個結點public Node(Object item, Node next) {this.item = item;this.next = next;}
}

?【在這里我們可以看到他用得是equals,由于字符串改寫了,其比較的是內容,之前的一個案例就在這里被解釋了】

【如果table沒到64,但是鏈表超過8,將會對table進行擴容】

?【下面的源碼更加說明了上面的結論】

package com.hspedu.set_;import java.util.HashSet;/*** @author 韓順平* @version 1.0*/
@SuppressWarnings({"all"})
public class HashSetSource {public static void main(String[] args) {HashSet hashSet = new HashSet();hashSet.add("java");//到此位置,第1次add分析完畢.hashSet.add("php");//到此位置,第2次add分析完畢hashSet.add("java");System.out.println("set=" + hashSet);/*對HashSet 的源碼解讀1. 執行 HashSet()public HashSet() {map = new HashMap<>();}2. 執行 add()public boolean add(E e) {//e = "java"return map.put(e, PRESENT)==null;//(static) PRESENT = new Object();}3.執行 put() , 該方法會執行 hash(key) 得到key對應的hash值 算法h = key.hashCode()) ^ (h >>> 16)public V put(K key, V value) {//key = "java" value = PRESENT 共享return putVal(hash(key), key, value, false, true);}4.執行 putValfinal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i; //定義了輔助變量//table 就是 HashMap 的一個數組,類型是 Node[]//if 語句表示如果當前table 是null, 或者 大小=0//就是第一次擴容,到16個空間.if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//(1)根據key,得到hash 去計算該key應該存放到table表的哪個索引位置//并把這個位置的對象,賦給 p//(2)判斷p 是否為null//(2.1) 如果p 為null, 表示還沒有存放元素, 就創建一個Node (key="java",value=PRESENT)//(2.2) 就放在該位置 tab[i] = newNode(hash, key, value, null)if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {//一個開發技巧提示: 在需要局部變量(輔助變量)時候,在創建Node<K,V> e; K k; ////如果當前索引位置對應的鏈表的第一個元素和準備添加的key的hash值一樣//并且滿足 下面兩個條件之一://(1) 準備加入的key 和 p 指向的Node 結點的 key 是同一個對象//(2)  p 指向的Node 結點的 key 的equals() 和準備加入的key比較后相同//就不能加入if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;//再判斷 p 是不是一顆紅黑樹,//如果是一顆紅黑樹,就調用 putTreeVal , 來進行添加else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//如果table對應索引位置,已經是一個鏈表, 就使用for循環比較//(1) 依次和該鏈表的每一個元素比較后,都不相同, 則加入到該鏈表的最后//    注意在把元素添加到鏈表后,立即判斷 該鏈表是否已經達到8個結點//    , 就調用 treeifyBin() 對當前這個鏈表進行樹化(轉成紅黑樹)//    注意,在轉成紅黑樹時,要進行判斷, 判斷條件//    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY(64))//            resize();//    如果上面條件成立,先table擴容.//    只有上面條件不成立時,才進行轉成紅黑樹//(2) 依次和該鏈表的每一個元素比較過程中,如果有相同情況,就直接breakfor (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD(8) - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;//size 就是我們每加入一個結點Node(k,v,h,next), size++if (++size > threshold)resize();//擴容afterNodeInsertion(evict);return null;}*/}
}

2.4?HashSet 課堂練習 1

package com.hspedu.set_;import java.util.HashSet;
import java.util.Objects;/*** @author 林然* @version 1.0*/
public class HashSetExercise {@SuppressWarnings("all")public static void main(String[] args) {/**定義一個 Employee 類,該類包含:private 成員屬性 name,age 要求:創建 3 個 Employee 對象放入 HashSet 中當 name 和 age 的值相同時,認為是相同員工, 不能添加到 HashSet 集合中*/HashSet hashSet = new HashSet();hashSet.add(new Employee("milan", 18));//okhashSet.add(new Employee("smith", 28));//okhashSet.add(new Employee("milan", 18));//加入不成功System.out.println("hashSet=" + hashSet);}
}
//創建 Employee
class Employee{private String name;private int age;public Employee(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;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Employee employee = (Employee) o;return age == employee.age &&Objects.equals(name, employee.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

?2.5?HashSet 課后練習 2

3.LinkedHashSet?

3.1?LinkedHashSet 的全面說明

package com.hspedu.set_;import java.util.LinkedHashSet;
import java.util.Set;@SuppressWarnings({"all"})
public class LinkedHashSetSource {public static void main(String[] args) {//分析一下LinkedHashSet的底層機制Set set = new LinkedHashSet();set.add(new String("AA"));set.add(456);set.add(456);set.add(new Customer("劉", 1001));set.add(123);set.add("HSP");System.out.println("set=" + set);//1. LinkedHashSet 加入順序和取出元素/數據的順序一致//2. LinkedHashSet 底層維護的是一個LinkedHashMap(是HashMap的子類)//3. LinkedHashSet 底層結構 (數組table+雙向鏈表)//4. 添加第一次時,直接將 數組table 擴容到 16 ,存放的結點類型是 LinkedHashMap$Entry//5. 數組是 HashMap$Node[] 存放的元素/數據是 LinkedHashMap$Entry類型/*//繼承關系是在內部類完成.static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}}*/}
}
class Customer {private String name;private int no;public Customer(String name, int no) {this.name = name;this.no = no;}
}

3.2?LinkedHashSet 課后練習題

package com.hspedu.set_;import java.util.LinkedHashSet;
import java.util.Objects;@SuppressWarnings({"all"})
public class LinkedHashSetExercise {public static void main(String[] args) {LinkedHashSet linkedHashSet = new LinkedHashSet();linkedHashSet.add(new Car("奧拓", 1000));//OKlinkedHashSet.add(new Car("奧迪", 300000));//OKlinkedHashSet.add(new Car("法拉利", 10000000));//OKlinkedHashSet.add(new Car("奧迪", 300000));//加入不了linkedHashSet.add(new Car("保時捷", 70000000));//OKlinkedHashSet.add(new Car("奧迪", 300000));//加入不了System.out.println("linkedHashSet=" + linkedHashSet);}
}/*** Car 類(屬性:name,price),  如果 name 和 price 一樣,* 則認為是相同元素,就不能添加。 5min*/class Car {private String name;private double price;public Car(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "\nCar{" +"name='" + name + '\'' +", price=" + price +'}';}//重寫equals 方法 和 hashCode//當 name 和 price 相同時, 就返回相同的 hashCode 值, equals返回t@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Car car = (Car) o;return Double.compare(car.price, price) == 0 &&Objects.equals(name, car.name);}@Overridepublic int hashCode() {return Objects.hash(name, price);}
}

?四、Map

1.Map 接口和常用方法?

1.1?Map 接口實現類的特點 [很實用]

package com.hspedu.map_;import java.util.HashMap;
import java.util.Map;/*** @author 林然* @version 1.0*/
public class Map_ {@SuppressWarnings("all")public static void main(String[] args) {//老韓解讀 Map 接口實現類的特點, 使用實現類 HashMap//1. Map 與 Collection 并列存在。用于保存具有映射關系的數據:Key-Value(雙列元素)//2. Map 中的 key 和 value 可以是任何引用類型的數據,會封裝到 HashMap$Node 對象中//3. Map 中的 key 不允許重復,原因和 HashSet 一樣,前面分析過源碼. //4. Map 中的 value 可以重復//5. Map 的 key 可以為 null, value 也可以為 null ,注意 key 為 null,// 只能有一個,value 為 null ,可以多個//6. 常用 String 類作為 Map 的 key//7. key 和 value 之間存在單向一對一關系,即通過指定的 key 總能找到對應的 valueMap map =new HashMap();map.put("no1","林然");//k-vmap.put("no2","林然2");//k-vmap.put("no1","張三豐");//k-v 當有相同的 k , 就等價于替換.map.put("no3","張三豐");//k-vmap.put(null,null);//k-vmap.put(null,"abc");//k-v 當有相同的 k , 就等價于替換map.put("no4",null);//k-vmap.put(1, "趙敏");//k-vmap.put(new Object(), "金毛獅王");//k-v// 通過 get 方法,傳入 key ,會返回對應的 valueSystem.out.println(map.get("no2"));//林然System.out.println(map);}
}

package com.hspedu.map_;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class MapSource_ {public static void main(String[] args) {Map map = new HashMap();map.put("no1", "韓順平");//k-vmap.put("no2", "張無忌");//k-vmap.put(new Car(), new Person());//k-v//老韓解讀//1. k-v 最后是 HashMap$Node node = newNode(hash, key, value, null)//2. k-v 為了方便程序員的遍歷,還會 創建 EntrySet 集合 ,該集合存放的元素的類型 Entry, 而一個Entry//   對象就有k,v EntrySet<Entry<K,V>> 即: transient Set<Map.Entry<K,V>> entrySet;//3. entrySet 中, 定義的類型是 Map.Entry ,但是實際上存放的還是 HashMap$Node//   這時因為 static class Node<K,V> implements Map.Entry<K,V>//4. 當把 HashMap$Node 對象 存放到 entrySet 就方便我們的遍歷, 因為 Map.Entry 提供了重要方法//   K getKey(); V getValue();Set set = map.entrySet();System.out.println(set.getClass());// HashMap$EntrySetfor (Object obj : set) {//System.out.println(obj.getClass()); //HashMap$Node//為了從 HashMap$Node 取出k-v//1. 先做一個向下轉型Map.Entry entry = (Map.Entry) obj;System.out.println(entry.getKey() + "-" + entry.getValue() );}Set set1 = map.keySet();System.out.println(set1.getClass());Collection values = map.values();System.out.println(values.getClass());}
}class Car {}class Person{}

1.2 常用方法

?

package com.hspedu.map_;import java.util.HashMap;
import java.util.Map;/*** @author 林然* @version 1.0*/public class MapMethod {public static void main(String[] args) {//演示 map 接口常用方法Map map = new HashMap();map.put("鄧超", new Book("", 100));//OKmap.put("鄧超", "孫儷");//替換-> 一會分析源碼map.put("王寶強", "馬蓉");//OKmap.put("宋喆", "馬蓉");//OKmap.put("劉令博", null);//OKmap.put(null, "劉亦菲");//OKmap.put("鹿晗", "關曉彤");//OKmap.put("hsp", "hsp 的老婆");System.out.println("map=" + map);
// remove:根據鍵刪除映射關系map.remove(null);System.out.println("map=" + map);
// get:根據鍵獲取值Object val = map.get("鹿晗");System.out.println("val=" + val);
// size:獲取元素個數System.out.println("k-v=" + map.size());
// isEmpty:判斷個數是否為 0System.out.println(map.isEmpty());//F
// clear:清除 k-v
//map.clear();System.out.println("map=" + map);
// containsKey:查找鍵是否存在System.out.println("結果=" + map.containsKey("hsp"));//T}
}class Book {private String name;private int num;public Book(String name, int num) {this.name = name;this.num = num;}
}

?1.3?Map 接口遍歷方法

package com.hspedu.map_;import java.util.*;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class MapFor {public static void main(String[] args) {Map map = new HashMap();map.put("鄧超", "孫儷");map.put("王寶強", "馬蓉");map.put("宋喆", "馬蓉");map.put("劉令博", null);map.put(null, "劉亦菲");map.put("鹿晗", "關曉彤");//第一組: 先取出 所有的 Key , 通過 Key 取出對應的 ValueSet keyset = map.keySet();//(1) 增強 forSystem.out.println("-----第一種方式-------");for (Object key : keyset) {System.out.println(key + "-" + map.get(key));}//(2) 迭代器System.out.println("----第二種方式--------");Iterator iterator = keyset.iterator();while (iterator.hasNext()) {Object key = iterator.next();System.out.println(key + "-" + map.get(key));}//第二組: 把所有的 values 取出Collection values = map.values();//這里可以使用所有的 Collections 使用的遍歷方法//(1) 增強 forSystem.out.println("---取出所有的 value 增強 for----");for (Object value : values) {System.out.println(value);}
//(2) 迭代器System.out.println("---取出所有的 value 迭代器----");Iterator iterator2 = values.iterator();while (iterator2.hasNext()){Object value = iterator2.next();System.out.println(value);}//第三組: 通過 EntrySet 來獲取 k-vSet entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>
//(1) 增強 forSystem.out.println("----使用 EntrySet 的 for 增強(第 3 種)----");for (Object entry : entrySet) {
//將 entry 轉成 Map.EntryMap.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}
//(2) 迭代器System.out.println("----使用 EntrySet 的 迭代器(第 4 種)----");Iterator iterator3 = entrySet.iterator();while (iterator3.hasNext()) {Object entry = iterator3.next();
//System.out.println(next.getClass());//HashMap$Node -實現-> Map.Entry (getKey,getValue)
//向下轉型 Map.EntryMap.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}}
}

?1.4?Map 接口課堂練習

package com.hspedu.map_;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class MapExercise {public static void main(String[] args) {//完成代碼Map hashMap = new HashMap();//添加對象hashMap.put(1, new Emp("jack", 300000, 1));hashMap.put(2, new Emp("tom", 21000, 2));hashMap.put(3, new Emp("milan", 12000, 3));//遍歷2種方式//并遍歷顯示工資>18000的員工(遍歷方式最少兩種)//1. 使用keySet  -> 增強forSet keySet = hashMap.keySet();System.out.println("====第一種遍歷方式====");for (Object key : keySet) {//先獲取valueEmp emp = (Emp) hashMap.get(key);if(emp.getSal() >18000) {System.out.println(emp);}}//2. 使用EntrySet -> 迭代器//   體現比較難的知識點//   慢慢品,越品越有味道.Set entrySet = hashMap.entrySet();System.out.println("======迭代器======");Iterator iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry entry =  (Map.Entry)iterator.next();//通過entry 取得key 和 valueEmp emp = (Emp) entry.getValue();if(emp.getSal() > 18000) {System.out.println(emp);}}}
}
/*** 使用HashMap添加3個員工對象,要求* 鍵:員工id* 值:員工對象** 并遍歷顯示工資>18000的員工(遍歷方式最少兩種)* 員工類:姓名、工資、員工id*/
class Emp {private String name;private double sal;private int id;public Emp(String name, double sal, int id) {this.name = name;this.sal = sal;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "Emp{" +"name='" + name + '\'' +", sal=" + sal +", id=" + id +'}';}
}

?2.Map 接口實現類-HashMap

2.1?HashMap 小結?

2.2?HashMap 底層機制及源碼剖析?

package com.hspedu.map_;import java.util.HashMap;@SuppressWarnings({"all"})
public class HashMapSource1 {public static void main(String[] args) {HashMap map = new HashMap();map.put("java", 10);//okmap.put("php", 10);//okmap.put("java", 20);//替換valueSystem.out.println("map=" + map);///*老韓解讀HashMap的源碼+圖解1. 執行構造器 new HashMap()初始化加載因子 loadfactor = 0.75HashMap$Node[] table = null2. 執行put 調用 hash方法,計算 key的 hash值 (h = key.hashCode()) ^ (h >>> 16)public V put(K key, V value) {//K = "java" value = 10return putVal(hash(key), key, value, false, true);}3. 執行 putValfinal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;//輔助變量//如果底層的table 數組為null, 或者 length =0 , 就擴容到16if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//取出hash值對應的table的索引位置的Node, 如果為null, 就直接把加入的k-v//, 創建成一個 Node ,加入該位置即可if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;//輔助變量// 如果table的索引位置的key的hash相同和新的key的hash值相同,// 并 滿足(table現有的結點的key和準備添加的key是同一個對象  || equals返回真)// 就認為不能加入新的k-vif (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)//如果當前的table的已有的Node 是紅黑樹,就按照紅黑樹的方式處理e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//如果找到的結點,后面是鏈表,就循環比較for (int binCount = 0; ; ++binCount) {//死循環if ((e = p.next) == null) {//如果整個鏈表,沒有和他相同,就加到該鏈表的最后p.next = newNode(hash, key, value, null);//加入后,判斷當前鏈表的個數,是否已經到8個,到8個,后//就調用 treeifyBin 方法進行紅黑樹的轉換if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash && //如果在循環比較過程中,發現有相同,就break,就只是替換value((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value; //替換,key對應valueafterNodeAccess(e);return oldValue;}}++modCount;//每增加一個Node ,就size++if (++size > threshold[12-24-48])//如size > 臨界值,就擴容resize();afterNodeInsertion(evict);return null;}5. 關于樹化(轉成紅黑樹)//如果table 為null ,或者大小還沒有到 64,暫時不樹化,而是進行擴容.//否則才會真正的樹化 -> 剪枝final void treeifyBin(Node<K,V>[] tab, int hash) {int n, index; Node<K,V> e;if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)resize();}*/}
}

3.Map 接口實現類-Hashtable

3.1 HashTable 的基本介紹

?擴容【2倍+1】

package com.hspedu.map_;import java.util.Hashtable;@SuppressWarnings({"all"})
public class HashTableExercise {public static void main(String[] args) {Hashtable table = new Hashtable();//oktable.put("john", 100); //ok//table.put(null, 100); //異常 NullPointerException//table.put("john", null);//異常 NullPointerExceptiontable.put("lucy", 100);//oktable.put("lic", 100);//oktable.put("lic", 88);//替換table.put("hello1", 1);table.put("hello2", 1);table.put("hello3", 1);table.put("hello4", 1);table.put("hello5", 1);table.put("hello6", 1);System.out.println(table);//簡單說明一下Hashtable的底層//1. 底層有數組 Hashtable$Entry[] 初始化大小為 11//2. 臨界值 threshold 8 = 11 * 0.75//3. 擴容: 按照自己的擴容機制來進行即可.//4. 執行 方法 addEntry(hash, key, value, index); 添加K-V 封裝到Entry//5. 當 if (count >= threshold) 滿足時,就進行擴容//5. 按照 int newCapacity = (oldCapacity << 1) + 1; 的大小擴容.}
}

3.2?Hashtable HashMap 對比

4.Map 接口實現類-Properties?

4.1基本介紹

4.2?基本使用?

package com.hspedu.map_;import java.util.Properties;/*** @author Linran* @version 1.0*/
@SuppressWarnings({"all"})
public class Properties_ {public static void main(String[] args) {//老韓解讀//1. Properties 繼承  Hashtable//2. 可以通過 k-v 存放數據,當然key 和 value 不能為 null//增加Properties properties = new Properties();//properties.put(null, "abc");//拋出 空指針異常//properties.put("abc", null); //拋出 空指針異常properties.put("john", 100);//k-vproperties.put("lucy", 100);properties.put("lic", 100);properties.put("lic", 88);//如果有相同的key , value被替換System.out.println("properties=" + properties);//通過k 獲取對應值System.out.println(properties.get("lic"));//88//刪除properties.remove("lic");System.out.println("properties=" + properties);//修改properties.put("john", "約翰");System.out.println("properties=" + properties);}
}

?五、總結-開發中如何選擇集合實現類(記住)

?5.1TreeSet源碼解讀

package com.hspedu.set_;import java.util.Comparator;
import java.util.TreeSet;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class TreeSet_ {public static void main(String[] args) {//1. 當我們使用無參構造器,創建TreeSet時,仍然是無序的//2. 老師希望添加的元素,按照字符串大小來排序//3. 使用TreeSet 提供的一個構造器,可以傳入一個比較器(匿名內部類)//   并指定排序規則//4. 簡單看看源碼/*1. 構造器把傳入的比較器對象,賦給了 TreeSet的底層的 TreeMap的屬性this.comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 在 調用 treeSet.add("tom"), 在底層會執行到if (cpr != null) {//cpr 就是我們的匿名內部類(對象)do {parent = t;//動態綁定到我們的匿名內部類(對象)comparecmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else //如果相等,即返回0,這個Key就沒有加入return t.setValue(value);} while (t != null);}*///        TreeSet treeSet = new TreeSet();TreeSet treeSet = new TreeSet(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//下面 調用String的 compareTo方法進行字符串大小比較//如果老韓要求加入的元素,按照長度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o1).length() - ((String) o2).length();}});//添加數據.treeSet.add("jack");treeSet.add("tom");//3treeSet.add("sp");treeSet.add("a");treeSet.add("abc");//3,并不會加入System.out.println("treeSet=" + treeSet);}
}

?5.2 TreeMap源碼解讀

package com.hspedu.map_;import java.util.Comparator;
import java.util.TreeMap;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class TreeMap_ {public static void main(String[] args) {//使用默認的構造器,創建TreeMap, 是無序的(也沒有排序)/*老韓要求:按照傳入的 k(String) 的大小進行排序*/
//        TreeMap treeMap = new TreeMap();TreeMap treeMap = new TreeMap(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//按照傳入的 k(String) 的大小進行排序//按照K(String) 的長度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o2).length() - ((String) o1).length();}});treeMap.put("jack", "杰克");treeMap.put("tom", "湯姆");treeMap.put("kristina", "克瑞斯提諾");treeMap.put("smith", "斯密斯");treeMap.put("hsp", "韓順平");//加入不了,會把湯姆修改成韓順平System.out.println("treemap=" + treeMap);/*老韓解讀源碼:1. 構造器. 把傳入的實現了 Comparator接口的匿名內部類(對象),傳給給TreeMap的comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 調用put方法2.1 第一次添加, 把k-v 封裝到 Entry對象,放入rootEntry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}2.2 以后添加Comparator<? super K> cpr = comparator;if (cpr != null) {do { //遍歷所有的key , 給當前key找到適當位置parent = t;cmp = cpr.compare(key, t.key);//動態綁定到我們的匿名內部類的compareif (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else  //如果遍歷過程中,發現準備添加Key 和當前已有的Key 相等,就不添加return t.setValue(value);} while (t != null);}*/}
}

?六、Collections 工具類

1 Collections 工具類介紹?

2 排序操作:(均為 static 方法)?

package com.hspedu.collections_;import java.util.*;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class Collections_ {public static void main(String[] args) {//創建 ArrayList 集合,用于測試.List list = new ArrayList();list.add("tom");list.add("smith");list.add("king");list.add("milan");list.add("tom");// reverse(List):反轉 List 中元素的順序Collections.reverse(list);System.out.println(list);// shuffle(List):對 List 集合元素進行隨機排序// for (int i = 0; i < 5; i++) {// Collections.shuffle(list);// System.out.println("list=" + list);//sort(List):根據元素的自然順序對指定 List 集合元素按升序排序Collections.sort(list);System.out.println("自然排序后");System.out.println("list=" + list);//按照首字母進行排序// sort(List,Comparator):根據指定的 Comparator 產生的順序對 List 集合元素進行排序
//我們希望按照 字符串的長度大小排序Collections.sort(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {
//可以加入校驗代碼.return ((String) o2).length() - ((String) o1).length();}});System.out.println("字符串長度大小排序=" + list);// swap(List,int, int):將指定 list 集合中的 i 處元素和 j 處元素進行交換
//比如Collections.swap(list, 0, 1);System.out.println("交換后的情況");System.out.println("list=" + list);//Object max(Collection):根據元素的自然順序,返回給定集合中的最大元素System.out.println("自然順序最大元素=" + Collections.max(list));//Object max(Collection,Comparator):根據 Comparator 指定的順序,返回給定集合中的最大元素
//比如,我們要返回長度最大的元素Object maxObject = Collections.max(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {return ((String)o1).length() - ((String)o2).length();}});System.out.println("長度最大的元素=" + maxObject);//Object min(Collection)//Object min(Collection,Comparator)//上面的兩個方法,參考 max 即可//int frequency(Collection,Object):返回指定集合中指定元素的出現次數System.out.println("tom 出現的次數=" + Collections.frequency(list, "tom"));//void copy(List dest,List src):將 src 中的內容復制到 dest 中ArrayList dest = new ArrayList();
//為了完成一個完整拷貝,我們需要先給 dest 賦值,大小和 list.size()一樣for(int i = 0; i < list.size(); i++) {dest.add("");}
//拷貝Collections.copy(dest, list);System.out.println("dest=" + dest);//boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替換 List 對象的所有舊值
//如果 list 中,有 tom 就替換成 湯姆Collections.replaceAll(list, "tom", "湯姆");System.out.println("list 替換后=" + list);}
}

七、本章作業

1.作業一?

package com.hspedu.homework;import java.util.ArrayList;
import java.util.Collections;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class homework1 {public static void main(String[] args) {News1 new1=new News1("新冠確診病例超千萬,數百萬印度教信徒赴恒河\"圣浴\"引民眾擔憂");News1 new2=new News1("男子突然想起2個月前釣的魚還在網兜里,撈起一看趕緊放生");ArrayList arrayList =new ArrayList();arrayList.add(new1);arrayList.add(new2);Collections.reverse(arrayList);for (Object k:arrayList) {News1 k1 = (News1)k;if(k1.getTitle().length()>=15)System.out.println(k1.getTitle().substring(0, 15) + "...");elseSystem.out.println(k1.getTitle());}}
}
class News1{private String title;private String content;public News1(String title) {this.title = title;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "News{" +"title='" + title + '\'' +", content='" + content + '\'' +'}';}
}

?2.作業二

package com.hspedu.homework;import java.util.ArrayList;
import java.util.Iterator;@SuppressWarnings({"all"})
public class Homework02 {public static void main(String[] args) {ArrayList arrayList = new ArrayList();Car car = new Car("寶馬", 400000);Car car2 = new Car("賓利",5000000);//1.add:添加單個元素arrayList.add(car);arrayList.add(car2);System.out.println(arrayList);//* 2.remove:刪除指定元素arrayList.remove(car);System.out.println(arrayList);//* 3.contains:查找元素是否存在System.out.println(arrayList.contains(car));//F//* 4.size:獲取元素個數System.out.println(arrayList.size());//1//* 5.isEmpty:判斷是否為空System.out.println(arrayList.isEmpty());//F//* 6.clear:清空//System.out.println(arrayList.clear(););//* 7.addAll:添加多個元素System.out.println(arrayList);arrayList.addAll(arrayList);//2個賓利System.out.println(arrayList);//* 8.containsAll:查找多個元素是否都存在arrayList.containsAll(arrayList);//T//* 9.removeAll:刪除多個元素//arrayList.removeAll(arrayList); //相當于清空//* 使用增強for和 迭代器來遍歷所有的car , 需要重寫 Car 的toString方法for (Object o : arrayList) {System.out.println(o);//}System.out.println("===迭代器===");Iterator iterator = arrayList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}}
}
/*** 使用ArrayList 完成對 對象 Car {name, price} 的各種操作* 1.add:添加單個元素* 2.remove:刪除指定元素* 3.contains:查找元素是否存在* 4.size:獲取元素個數* 5.isEmpty:判斷是否為空* 6.clear:清空* 7.addAll:添加多個元素* 8.containsAll:查找多個元素是否都存在* 9.removeAll:刪除多個元素* 使用增強for和 迭代器來遍歷所有的car , 需要重寫 Car 的toString方法*/
class Car {private String name;private double price;public Car(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "Car{" +"name='" + name + '\'' +", price=" + price +'}';}
}

?3.作業三

package com.hspedu.homework;import java.util.*;/*** @author 林然* @version 1.0*/
public class homework3 {@SuppressWarnings("all")public static void main(String[] args) {Map m = new HashMap();m.put("jack",650);m.put("tom",1200);m.put("smith",2900);m.replace("jack",2600);Set keys =m.keySet();//更新工資for(Object k :keys){   int salary=(int)(m.get(k));m.replace(k,salary+100);}//遍歷集合中的員工//遍歷 EntrySetSet entrySet = m.entrySet();//迭代器Iterator iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry entry =  (Map.Entry)iterator.next();System.out.println(entry.getKey() + "-" + entry.getValue());}System.out.println("====遍歷所有的工資====");Collection values = m.values();for (Object value : values) {System.out.println("工資=" + value);}}
}

?4.作業四

5.作業五?

//package com.hspedu.homework;
//
//import java.util.TreeSet;
////@SuppressWarnings({"all"})
//public class Homework05 {
//    public static void main(String[] args) {
//        TreeSet treeSet = new TreeSet();
//        //分析源碼
//        //add 方法,因為 TreeSet() 構造器沒有傳入Comparator接口的匿名內部類
//        //所以在底層 Comparable<? super K> k = (Comparable<? super K>) key;
//        //即 把 Perosn轉成 Comparable類型
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//
//        System.out.println(treeSet);
//
//    }
//}
//
//class Person implements Comparable{
//
//    @Override
//    public int compareTo(Object o) {
//        return 0;
//    }
//}

?6.作業六

【只要id和name不一樣,那么我們認為他們不是同一個對象】

【remove中是利用1001和CC來計算哈希值,也就是他沒辦法找到p1所在的位置【1001+AA】】

package com.hspedu.homework;import java.util.HashSet;
import java.util.Objects;@SuppressWarnings({"all"})
public class Homework06 {public static void main(String[] args) {HashSet set = new HashSet();//okPerson p1 = new Person(1001,"AA");//okPerson p2 = new Person(1002,"BB");//okset.add(p1);//okset.add(p2);//okp1.name = "CC";set.remove(p1);System.out.println(set);//2set.add(new Person(1001,"CC"));System.out.println(set);//3set.add(new Person(1001,"AA"));System.out.println(set);//4}
}class Person {public String name;public int id;public Person(int id, String name) {this.name = name;this.id = id;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return id == person.id &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, id);}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", id=" + id +'}';}
}

7.作業七

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/213108.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213108.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213108.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設計模式之GoF23介紹

深入探討設計模式&#xff1a;構建可維護、可擴展的軟件架構 一、設計模式的背景1.1 什么是設計模式1.2 設計模式的歷史 二、設計模式的分類2.1 創建型模式2.2 結構型模式2.3 行為型模式 三、七大設計原則四、設計模式關系結論 :rocket: :rocket: :rocket: 在軟件開發領域&…

算法:爬樓梯(迭代和動態規劃)

迭代 時間復雜度 O(n) 空間復雜度 O(1) /*** param {number} n* return {number}*/ var climbStairs function(n) {let l 0, r 0 , sum 1for(let i1; i<n; i){l rr sumsum l r}return sum }; 動態規劃 時間復雜度 O(n) 空間復雜度 O(n) /*** param {number} n* r…

Memcached學習

一、概念 Memcached是一個開源的&#xff0c;高性能的內存緩存軟件&#xff0c;從名稱上看Mem就是內存&#xff0c;二cache是緩存。作用通過在事先規劃好的內存空間中臨時緩存數據庫中的各類數據&#xff0c;以達到減少業務對數據庫的直接高并發訪問&#xff0c;從而達到提升數…

【密碼學基礎】Diffie-Hellman密鑰交換協議

DH介紹 Diffie-Hellman密鑰協議算法是一種確保共享密鑰安全穿越不安全網絡的方法。 這個機制的巧妙在于需要安全通信的雙方可以用這個方法確定對稱密鑰&#xff0c;然后可以用這個密鑰進行加密和解密。 但是注意&#xff0c;這個密鑰交換協議 只能用于密鑰的交換&#xff0c;而…

Java面試題(每天10題)-------連載(45)

Dubbo篇 1、Dubbo的服務調用流程 2、Dubbo支持那種協議&#xff0c;每種協議的應用場景&#xff0c;優缺點&#xff1f; dubbo&#xff1a; 單一長連接和 NIO 異步通訊&#xff0c;適合大并發小數據量的服務調用&#xff0c;以及消費者遠大于提供者。傳輸協議 TCP&#xff0c;…

Proteus仿真--射擊小游戲仿真設計

本文介紹基于proteus射擊小游戲仿真設計&#xff08;完整仿真源文件及代碼見文末鏈接&#xff09; 仿真圖如下 K1-K4為4個按鍵&#xff0c;用于上移、下移、確認等&#xff0c;模擬單機游戲 仿真運行視頻 Proteus仿真--射擊小游戲仿真設計 附完整Proteus仿真資料代碼資料 …

ArcGIS界面顯示分辨率調整

因為電腦顯示分辨率的問題呢&#xff0c;ArcGIS的界面顯示會字體顯示不合適&#xff0c;出現模糊情況&#xff0c;這時候只需要做個簡單的操作設置一下便可以解決&#xff01; 1、右鍵ArcMap的快捷啟動方式。 2、對應選擇兼容性——>更高DPI設置——>勾選替代DPI縮放行為…

自然場景圖像中的文本檢測綜述

摘 要 本文對自然場景文本檢測問題及其方法的研究進展進行了綜述. 首先, 論述了自然場景文本的特點、自然場景文本檢測技術的研究背景、現狀以及主要技術路線. 其次, 從傳統文本檢測以及深度學習文本檢測的視角出發, 梳理、分析并比較了各類自然場景文本檢測方法的優缺點, 并介…

體系化學習運籌學基礎算法的實踐和總結

文章目錄 引言目標設計目標實踐文章匯總經驗總結一則預告 引言 眨眼間已經12月了&#xff0c;眼看著2023年馬上要過完了。 女朋友最近總說&#xff0c;工作以后感覺時間過的好快。事實上&#xff0c;我也是這么認為的。年紀越大&#xff0c;越會擔心35歲危機的降臨。所以&…

Xubuntu16.04系統中使用EDIMAX EW-7822UAC無線網卡開啟5G自發AP

目錄 1.關于 EDIMAX EW-7822UAC2.驅動安裝3.查看無線網卡信息3.通過create_ap配置5G自發AP 1.關于 EDIMAX EW-7822UAC 官網介紹 https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/wireless_adapters_ac1200_dual-band/ew-7822uac/ 詳細參數…

Python開發運維:Python項目發布到K8S集群

目錄 一、實驗 1.Python項目發布到K8S集群 一、實驗 1.Python項目發布到K8S集群 &#xff08;1&#xff09;獲取應用程序代碼 #把hello-python.tar.gz壓縮包上傳到k8s控制節點master1的root下&#xff0c;手動解壓 tar zxvf hello-python.tar.gz &#xff08;2&#xff0…

【Linux】進程周邊001之進程概念

&#x1f440;樊梓慕&#xff1a;個人主頁 &#x1f3a5;個人專欄&#xff1a;《C語言》《數據結構》《藍橋杯試題》《LeetCode刷題筆記》《實訓項目》《C》《Linux》 &#x1f31d;每一個不曾起舞的日子&#xff0c;都是對生命的辜負 目錄 前言 1.基本概念 2.描述進程-PCB…

LeetCode5.最長回文子串

昨天和之前打比賽的隊友聊天&#xff0c;他說他面百度面到這道算法題&#xff0c;然后他用暴力法解的&#xff0c;面試官讓他優化他沒優化出來&#xff0c;這道題我之前沒寫過&#xff0c;我就想看看我能不能用效率高一點的方法把它做出來&#xff0c;我一開始就在想用遞歸或者…

springboot(ssm滁州市特產銷售系統 特產商城系統Java系統

springboot(ssm滁州市特產銷售系統 特產商城系統Java系統 開發語言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服務器&#xff1a;tomcat 數據庫&#xff1a;mysql 5.7&#xff08;或8.0&#xff09; …

解決錯誤:sudo debtap -u curl: (22) The requested URL returned error: 404

具體錯誤 $ sudo debtap -u > Synchronizing pkgfile database... :: Updating 2 repos...core is up to dateextra is up to date > Synchronizing debtap database...% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload …

設計CPU功能的數字電路

實驗目的(1)熟悉Multisim 電路仿真軟件的操作界面和功能; (2)掌握邏輯電路綜合設計,并采用仿真軟件進行仿真。 實驗內容1.試設計一個簡易CPU功能的數字電路,實驗至少要求采用4個74HC/HCT194作為4個存儲單元(可以預先對存儲單元存儲數據),74HC283作為計算單元。請實現…

用相似對角矩陣加速矩陣的冪,以斐波那契數列為例

《用相似對角矩陣加速矩陣的冪&#xff0c;以斐波那契數列為例》 在計算機科學和線性代數領域&#xff0c;矩陣的冪是一個常見而重要的問題。特別是對于大型矩陣&#xff0c;直接計算冪可能會變得十分耗時。然而&#xff0c;通過相似對角矩陣的方法&#xff0c;我們能夠以更為…

多維時序 | MATLAB實現RIME-CNN-LSTM-Multihead-Attention多頭注意力機制多變量時間序列預測

多維時序 | MATLAB實現RIME-CNN-LSTM-Multihead-Attention多頭注意力機制多變量時間序列預測 目錄 多維時序 | MATLAB實現RIME-CNN-LSTM-Multihead-Attention多頭注意力機制多變量時間序列預測預測效果基本介紹模型描述程序設計參考資料 預測效果 基本介紹 MATLAB實現RIME-CNN-…

python字符串格式化--數字精度控制和快速寫法與表達式格式化

數字精度控制 我們可以使用m.n來控制數字的寬度和精度&#xff1a; m是寬度&#xff0c;設置必須為數字&#xff0c;且如果設置的數字小于本身&#xff0c;則不生效n控制小數點精度&#xff0c;必須為數字&#xff0c;會進行四舍五入 示例&#xff1a; 5d&#xff1a;是將寬…

idea本地調試hadoop 遇到的幾個問題

1.DEA對MapReduce的toString調用報錯&#xff1a;Method threw ‘java.lang.IllegalStateException‘ exception. Cannot evaluate org.apache.hadoop.mapreduc 解決方法&#xff1a;關閉 IDEA 中的啟用“ tostring() ”對象視圖 2.代碼和hdfs路徑都對的情況下&#xff0c;程序…