【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet
文章目錄
- 1.堆棧/隊列/數組/鏈表:數據結構即計算機組織管理數據的方式,堆棧指的是內存圖中的棧,不是堆
- 2.紅黑樹:二查,二查平,二查平1倍
- 3.List子接口:集合,IndexOutOfBoundsException
- 4.ArrayList的擴容原理:Stringbuild默認長度=16,擴容2倍
- 5.LinkedList:push堆棧
- 6.set子接口:單例=keySet
- 7.Object類的hashcode方法:對象的真正的內存地址(無限種)->哈希碼 (43億不到的可能)。極端下多個明文 -> 同一密文 (哈希碰撞)。打印對象,.toString(),.hashCode()
- 8.String類的hashcode方法:a97,碰撞
- 9.哈希表(HashSet)原理:元素不重復
- 10.linkedHashset和Hashset區別:A a = new A(){},coll.iterator().hasNext()
- 11.Map:Map和Collection是并列關系,Map.Entry < Integer,String > 是數據類型
- 12.內部接口:除了Inner訪問受限于Outer,這兩各自獨立
- 13.統計字符出現個數:.containsKey(.charAt)
- 14.debug:斷點/單點/高級調試
- 14.1 單步調試:over,into,out
- 14.1.1 step over
- 14.1.2 step into
- 14.1.3 Force step into
- 14.1.4 step out
- 14.1.5 Drop frame
- 15.2 高級調試:
- 15.2.1 跨斷點調試
- 15.2.2 查看斷點
- 15.2.3 設置變量值
- 16.斗地主:list.addAll(set)
- 17.Collections類和TreeSet:return o1-o2是升序
- 17.1 自定義MyCollections類來模擬完成addAll()和sort()方法
1.堆棧/隊列/數組/鏈表:數據結構即計算機組織管理數據的方式,堆棧指的是內存圖中的棧,不是堆
如下查詢慢:知道張三在哪,不能馬上知道王五在哪,挨個查。如下增刪雖然不用整個動(如刪除李四,只需要將箭頭指向王五就行),但是還是要先查找到再刪除,效率還是慢。但是直接刪除張三或馬六頭尾元素快。
2.紅黑樹:二查,二查平,二查平1倍
二叉樹:每個節點最多兩個子節點。查找樹:左小右大(二分法)。平衡樹:左右盡量相等(一邊的節點層次不會超過另一邊的兩倍)。二查平1倍:紅黑樹(數組和鏈表折中方案)。
二叉搜索樹BST(二查):插入或查詢一節點時,樹的每一行只需要和這一行的一個節點比較(因為左小右大),復雜度完全依賴樹深度。樹的行數即高度=logn【n為節點總數,2的樹行數次方為n】,BST讀和寫的復雜度都為logn。
有序數組:查找時用二分查找法(和BST像),時間復雜度也為logn。有序數組查詢最差情況logn,而當BST為單邊時(最差情況),BST查詢和插入都為o(n)。為什么很多情況下用BST,而不是有序數組二分查找?因為有序數組查找用二分查找logn,但是插入(不是查)要移動,插入時間復雜度為o(n)。
BST很少在語言內部數據結構存儲里用(因為下面直線情況),自平衡二叉樹AVL(二查平)是BST(二查)的繼承優化:左子樹和右子樹都是平衡二叉樹,而且左子樹和右子樹深度之差絕對值不會超過1(左旋和右旋),AVL讀和寫的復雜度最差情況都為O(logn)。
AVL平衡左右子樹相差1,這個條件很苛刻,導致很多情況下都不滿足這個平衡條件,需要旋轉變換,變換的話需要浪費時間。紅黑樹(二平查1倍)平衡條件更加寬松些左右深度差一倍即> = 節點數相同,< = 節點數差一倍(因為紅節點的子節點必須為黑即黑紅相間)。葉子節點(最后一個)和null節點都為黑節點
這樣寬松條件導致我們在插入節點時候變化更少的,所以紅黑樹寫的性能會高一些,所以treemap/hashmap底層采用紅黑樹(BST會變直線,AVL左右只能差1)。
如下是紅黑樹的插入變色流程:最上面根節點必須為黑,插入節點(為葉子節點)必為紅節點(看插入節點的父節點和父節點的兄弟節點即叔節點)。null節點算葉子節點即黑節點,當前插入的003是爺爺節點001的右右。
如下左旋+變色。
3.List子接口:集合,IndexOutOfBoundsException
package com.itheima01.list; import java.util.ArrayList; import java.util.List; /*Collection子接口:List1. List的特點:重索序1. 有先后順序:元素存儲的順序和取出的順序相同2. 具有整數索引,就是下標3. 允許重復元素2. List的方法(帶索引)(List特有的,共有的在Collection講過)1. add(int index, E element) :往索引位置添加一個元素1. Java中的 三個越界異常1. IndexOutOfBoundsException 集合2. ArrayIndexOutOfBoundsException 數組3. StringIndexOutOfBoundsException 字符串越界2. get(int index):獲取指定索引的元素3. remove(int index):移除指定索引的元素4. set(int index, E element) :修改指定索引的元素值 */ public class ListDemo {public static void main(String[] args) { // add();List<String> list = new ArrayList<>();list.add("周楠");list.add("王鳳枝");list.add("王凱");String s = list.get(2);System.out.println(s); //王凱list.remove(2);System.out.println(list); //[周楠, 王鳳枝]list.set(1,"昌老師");System.out.println(list); //[周楠, 昌老師]}//11111111111111111111111111111111111111111111111111111111111111111111111111111private static void add() {List<String> list = new ArrayList<>();list.add("周楠");list.add("王鳳枝");list.add("王凱");/*add(int index, element)往指定索引位添加元素index = list.size()IndexOutOfBoundsException: : 索引越界異常*/list.add(3,"田鎖"); //不越界,4越界System.out.println(list);String[] array = {};//System.out.println(array[0]); //ArrayIndexOutOfBoundsException : 數組索引越界String str = "abc"; // 字符串底層也是數組// char c = str.charAt(3); //索引0,1,2 // System.out.println(c); //StringIndexOutOfBoundsException:字符串索引越界} }4.ArrayList的擴容原理:Stringbuild默認長度=16,擴容2倍
ArrayList底層是存Object數組,擴容新建一個長度為原來1.5倍新數組(空)。
如下10進制的4就是2進制的0100(8421),3/2=1,ArrayList.java源碼中出現左右移(二進制右移一位相當于十進制/2)。
5.LinkedList:push堆棧
package com.itheima01.list; import java.util.LinkedList; /*LinkedList特點1. 底層數據結構: 雙向鏈表2. 查詢速度慢,增刪快(增刪需求多而且增刪首尾用LinkedList)3. 特有方法(不能使用多態,父類不能調子類特有方法)1. addFirst 元素添加在鏈表開頭2. addLast(add相同) 元素添加在鏈表結尾3. getFirst 獲取鏈表開頭4. getLast 獲取鏈表結尾5. removeFirst 移除并返回鏈表開頭6. removeLast 移除并返回鏈表結尾//下面兩個不需要掌握7. pop 從此列表所表示的堆棧處彈出一個元素(最頂部元素彈出,removeFirst)8. push 將元素推入此列表所表示的堆棧(元素存儲到集合頂部,addFirst) */ public class LinkedListDemo {public static void main(String[] args) { // method01();LinkedList<String> list = new LinkedList<>();list.add("張三"); // 是鏈表,不是按堆棧結構添加元素list.add("李四");list.add("王五");// 鏈表 -> 堆棧 ,張三在棧頂 // String pop = list.pop(); // 彈棧: 棧頂元素() // String removeFirst = list.removeFirst();//效果同上 // System.out.println(pop);list.push("王二"); //棧頂添加,效果等同于addSystem.out.println(list);}private static void method01() {LinkedList<String> list = new LinkedList<>();list.add("張三");list.add("李四");list.add("王五");list.addFirst("王二");list.addLast("馬六");System.out.println(list);String first = list.getFirst();String last = list.getLast();System.out.println(first + "," + last);System.out.println(list);list.removeFirst();list.removeLast();System.out.println(list);} }6.set子接口:單例=keySet
package com.itheima02.set; import java.util.HashSet; import java.util.Set;public class SetDemo {public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("張三");set.add("李四");boolean result = set.add("王五");System.out.println(result); //true boolean result2 = set.add("王五");System.out.println(result2); //false //元素不可重復System.out.println(set);//[李四,張三,王五] //存取不保證順序} }7.Object類的hashcode方法:對象的真正的內存地址(無限種)->哈希碼 (43億不到的可能)。極端下多個明文 -> 同一密文 (哈希碰撞)。打印對象,.toString(),.hashCode()
package com.itheima03.hash; /* * Object類有一個方法: int hashCode() : 返回該對象的哈希碼值。 * 1. 原理: 將對象的真正的內存地址(明文) 進行 哈希算法 加密之后產生的 哈希碼值(密文) * 2. 加密 : * 明文 : 大家都看的懂東西 I love you * 密文 : 明文經過加密算法變成密文 J mpwf zpv * 加密算法: 數學 (凱撒加密: 字母按字母表右移動一位) * 破解: 頻率分析法 (e i -> d h),截獲大量數據進行大數據分析e,i出現頻率最高,密文中出現最多的是d,h * * 哈希算法: 公開 * 基本保證 一個明文 -> 一個密文 不同明文不同的密文 * 告訴你算法,告訴你密文, 算不出明文 * * 3. 源碼: public native int hashCode(); 本地方法 * native(本地關鍵字) 修飾的方法沒有java方法體 (方法實現在JVM底層, 用C語言寫的) * 返回值 int (43億不到的可能) */ public class HashcodeDemo {public static void main(String[] args) {Person p = new Person();System.out.println(p); //com.itheima03.hash.Person@14ae5a5// return getClass().getName() + "@" + Integer.toHexString(hashCode());System.out.println(p.toString());//com.itheima03.hash.Person@14ae5a5 // 上面兩個打印結果都一樣 // 如下內存地址: 16進制哈希碼值14ae5a5 和下面10進制相等System.out.println(p.hashCode()); // 10進制: 21685669} } class Person{ }8.String類的hashcode方法:a97,碰撞
String s1 = “abc”,如下h就是hash值(只看最后一個h),b是98,c是99。
9.哈希表(HashSet)原理:元素不重復
hashcode(密文)為HashSet(HashSet底層數據結構是hash表)做鋪墊。如下三個abc字符串都為96354。問題:HashSet如何判定這個元素是否跟已存在的元素是重復即如下[重地,通話,abc,acD]?Set不存重復元素。S3因為是new出來的,和S1,S2明文即真正的內存地址不一樣。
下面S1,S4,S5,S6都是不重復元素。豎:暗文或暗文%16同(因為數組長度為16),equal不一樣。橫:明文和暗文和equal都不一樣。HashSet是效率最高的set且元素不重復,同一鏈表(豎)hashcode一樣,但是鏈表如果太長查詢慢,所以假如同一hash值(hashcode)碰撞了8次,鏈表重構為紅黑樹。
同一鏈表上都hash碰撞,數組的第一個位置余數=0,第二個位置余數=1。。。16的容量為什么到16*0.75=12就擴容了?再哈希rehash(余數重新算)這段時間內,16沒滿,我還有的用,如果rehash非常快就不用提前。
沒有重寫Person類的hashcode和equals方法。
如下重寫…如下就是hash表的應用:元素不重復,效率高。
10.linkedHashset和Hashset區別:A a = new A(){},coll.iterator().hasNext()
package com.itheima00.question; import java.util.HashSet; import java.util.LinkedHashSet; /* * Set: 不保證 存入和取出順序一致 * HashSet : 無序 * LinkedHashSet : 多個另一個鏈表, 來記錄存入的順序,有序即取出有序,所以效率變低(少用) */ public class Demo01 {public static void main(String[] args) {HashSet<String> set = new LinkedHashSet<>(); //向上轉型set.add("張三");set.add("李四");set.add("王五");set.add("馬六");System.out.println(set); //打印出有序的,LinkedHashSet不同于HashSet } } package com.itheima00.question; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;public class Demo02 {public static void main(String[] args) {Collection<String> coll = new ArrayList<String>(); //Collection是接口coll.add("張三");coll.add("張三2");coll.add("張三3"); // Iterator接口類型 變量 = 其實現類對象 (多態的向上轉型)/* Iterator<String> it = coll.iterator(); //Collection即coll是接口,接口調用方法執行子類ArrayList重寫的iterator()while(it.hasNext()){String name = it.next();System.out.println(name); //張三 張三2 張三3}*/// while(coll.iterator().hasNext()){ //不能這樣把it換了鏈式編程,原因如下圖 // String name = coll.iterator().next(); // System.out.println(name); // }}//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111public static void method01(){MyClass mc = new MyClass();A a = mc.test(); //右邊返回必然是A接口實現類對象即向上轉型,不需要new //上行等同于Iterator<String> it = coll.iterator(); 不一定需要看到new A a2 = new A() { //java中對象不一定看到new才放心 //new一個實現接口的匿名內部類A,使用{}具體實現接口 @Overridepublic void show() {}} ;} } interface A{void show(); } class MyClass{public A test(){ //返回A接口,不寫void // A a = new A(){}; //匿名內部類 // return a;return new A() { //下面等同于上面兩行,return A接口的子類對象@Overridepublic void show() {}};} }11.Map:Map和Collection是并列關系,Map.Entry < Integer,String > 是數據類型
package com.itheima01.map; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /*Map中的方法1. Map<K,V> <泛型>: K 表示作為鍵的類型,V表示值的類型2. put: 存儲鍵值對1. 鍵值對存儲到集合中 V put (K,V)2. 如果存儲了相同的鍵,覆蓋原有的值3. 返回值:一般返回null,如果存儲了重復的鍵,返回被覆蓋之前的值3. get:通過鍵,取出鍵對應的值1. V get(K),傳遞鍵,返回對應的值2. 如果集合中沒有這個鍵,返回null4. remove:移除鍵值對1. V remove(K),傳遞鍵,移除這個鍵值對2. 返回值:移除之前的值(無此鍵,則返回null)5. keySet: 將集合中所有的鍵,存儲到Set集合中6. entrySet:獲取到Map集合中所有的鍵值對存入Set接中7. size:獲取map集合的大小 * Map: * 1. key不可以重復 * 2. value可以重復 * 如果key存在,那么新value覆蓋舊value */ public class MapDemo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();map.put(1,"張三");map.put(2,"李四");map.put(3,"王五");map.put(4,"王五");map.put(3,"馬六"); //覆蓋王五System.out.println(map);//{1=張三,2=李四,3=馬六,4=王五}String name = map.get(5); //null,不是越界異常,無索引String name = map.get(3); //從key獲取valueSystem.out.println(name);//馬六//根據key刪除key-valuemap.remove(3);System.out.println(map);System.out.println(map.size()); //3,幾個k} }如下key不可重復,所以放到set集合(單例)。如下兩種遍歷方式都涉及set:
如下吳彥祖應該在第二個,存取無序,解決:HashMap換成LinkedHashMap。
12.內部接口:除了Inner訪問受限于Outer,這兩各自獨立
package com.itheima02.inner; import java.lang.reflect.Field; import java.util.Date; import com.itheima02.inner.Outer.Inner; /* * inner class : 訪問受限, 受限于外部類 * 有兩個包是不用導入:1. java.lang (String,Object) * 2. 當前類所在的包 * 1和2的子包都要導(如內部接口就在當前包的子包下) */ public class InnerDemo {public static void main(String[] args) { // new Date()new String("");new Object(); // new Field(); //java.lang包的子包,要導包} }//1111111111111111111111111111111111111111111111111111111111111111111111111111111111111 interface Outer{//public static final //因為Outer是接口,所以不能實例化,只能接口.。所以final讓I變為常量,static讓I可用接口名.直接調用int I = 1;//public abstractvoid outerMethod();//new外部類對象不需要new內部類對象,同理實現Outer接口不需要實現Inner接口//public static //外部接口不能創建實例來調用,所以接口名調用,所以靜態。上面Map.Entry即外接口.內接口(Entry是Map的內接口)interface Inner{ void innerMethod();} } class A implements Outer{ //不需要實現Inner@Overridepublic void outerMethod() {} } class B implements Outer.Inner{@Overridepublic void innerMethod() {} } class C implements Outer,Inner{//上面導過包了,Inner不用寫成Outer.Inner@Overridepublic void outerMethod() {}@Overridepublic void innerMethod() {} }13.統計字符出現個數:.containsKey(.charAt)
統計字符串中:大小寫字母及數字字符個數:https://blog.csdn.net/weixin_43435675/article/details/107434867
package com.itheima03.impl; import java.util.HashMap; /* * 需求: 計算一個字符串中每個字符出現次數。 * 0. 弄一個Map : 記錄 字符=次數 (就像畫正字選票) * char int * 1. 遍歷這個字符串,取出每個字符 * 2. 判斷Map中是否存在這個字符-> boolean containsKey(Object key) 如果此映射包含指定鍵的映射關系,則返回 true。 * 3. 有: 在對應的次數+1 。沒有 : 字符char=1 存進去 */ public class CountDemo {public static void main(String[] args) {String str = "abcaba"; HashMap<Character, Integer> map = new HashMap<>();//泛型不接收基本類型,所以char寫成Character,int的包裝類Integerfor(int i=0; i<str.length();i++){char c = str.charAt(i); //相應索引訪問到相應字符boolean result = map.containsKey(c); //一開始map為空,下面依次寫進去if(result){ // 存在,次數value+1Integer value = map.get(c); //c是key即char // value = value + 1; // map.put(c,value);// value++; // map.put(c,value);// int count = ++value; // map.put(c,count);map.put(c,++value); //不能寫成map.put(c,value++);}else{ // 不存在, 存入c=1map.put(c,1);}}System.out.println(map);} }14.debug:斷點/單點/高級調試
先設斷點再點擊如下進入調試。
紅色的箭頭指向的是現在調試程序停留的代碼行:方法 f2() 中,程序的第11行。紅色箭頭懸停的區域是程序的方法調用棧區。在這個區域中顯示了程序執行到斷點處所調用過的所有方法,越下面的方法被調用的越早。
14.1 單步調試:over,into,out
14.1.1 step over
點擊紅色箭頭指向的按鈕,程序向下執行一行(如果當前行有方法調用,這個方法將被執行完畢返回,然后到下一行)。
14.1.2 step into
點擊紅色箭頭指向的按鈕,程序向下執行一行。如果該行有自定義方法,則運行進入自定義方法(不會進入官方類庫的方法)。具體步驟如下:在自定義方法發f1()處設置斷點,執行調試。
點擊如下。
14.1.3 Force step into
該按鈕在調試的時候能進入任何方法。
14.1.4 step out
如果在調試的時候你進入了一個方法(如f2()),并覺得該方法沒有問題,你就可以使用stepout跳出該方法,返回到該方法被調用處的下一行語句。值得注意的是,該方法已執行完畢。
14.1.5 Drop frame
點擊該按鈕后,你將返回到當前方法的調用處(如上圖,程序會回到main()中)重新執行,并且所有上下文變量的值也回到那個時候。只要調用鏈中還有上級方法,可以跳到其中的任何一個方法。
15.2 高級調試:
15.2.1 跨斷點調試
設置多個斷點,開啟調試。想移動到下一個斷點,點擊如下圖:
程序將運行一個斷點到下一個斷點之間需要執行的代碼。如果后面代碼沒有斷點,再次點擊該按鈕將會執行完程序。
15.2.2 查看斷點
點擊箭頭指向的按鈕,可以查看你曾經設置過的斷點并可設置斷點的一些屬性。
箭頭1指向的是你曾經設置過的斷點,箭頭2可以設置條件斷點(滿足某個條件的時候,暫停程序的執行,如 c==97)。結束調試后,應該在箭頭1處把所設的斷點刪除(選擇要刪除的斷點后,點擊上方的紅色減號)。
15.2.3 設置變量值
調試開始后,在紅箭頭指向的區域可以給指定的變量賦值(鼠標左鍵選擇變量,右鍵彈出菜單選擇setValue…)。這個功能可以更加快速的檢測你的條件語句和循環語句。
16.斗地主:list.addAll(set)
package com.itheima04.Poker; import java.util.ArrayList; import java.util.Collections; // 寫一個規則: 2 > A > K > Q > J ...(不行,組合方式太多2也要>K) //上次寫的沒有排序 //黑紅梅方 public class SortDemo {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>(); //重索序list.add(3);list.add(5);list.add(4);list.add(1);list.add(2);System.out.println(list); //[3,5,4,1,2],有序Collections.sort(list);System.out.println(list);//[1,2,3,4,5]} }15發給第一個,13發給第二個。。。
17.Collections類和TreeSet:return o1-o2是升序
package com.itheima05.collections; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /*Arrays數組工具類, Objects對象工具類(命名規則最后+s)- java.utils.Collections是集合工具類,用來對集合進行操作。 常用方法如下: - public static void shuffle(List<?> list):打亂集合順序。 - public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。 - public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。 */ public class CollectionsDemo01 {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>(); //Integer源碼實現了Comparable接口 Collections.addAll(list,5,3,2,4,1); //System.out.println(list); //[3,4,5,1,2]// Collections.sort(list); // 默認: 升序// 如下第二個參數類型是Comparator接口,必須傳入接口實現類對象:new Comparator...后面全是匿名內部類Collections.sort(list, new Comparator<Integer>() { // 自定義升降序規則 , 任何排序都是兩兩比較 @Overridepublic int compare(Integer o1, Integer o2) { // return o1 - o2;//升序: 從小到大return o2 - o1;//降序: 從大到小}});System.out.println(list);} }17.1 自定義MyCollections類來模擬完成addAll()和sort()方法
package com.itheima05.collections; import java.util.ArrayList; import java.util.Comparator;public class MyCollections { // 1. addAll方法public static void addAll(ArrayList<Integer> list, Integer... args){for (Integer arg : args) {list.add(arg);}}//2. sort方法: 這里采用冒泡排序。collections底層實際是Timsort排序。//注意: 第二個參數是接口,必須傳入接口實現類(這將形成多態: 父接口引用調用方法執行的是子類重寫方法)public static void sort(ArrayList<Integer> list, Comparator<Integer> comparator) {int temp;for (int i = 0; i < list.size() - 1; i++) {for (int j = 0; j < list.size() - i - 1; j++) { int result = comparator.compare(list.get(j + 1), list.get(j));//j+1和j相鄰比較,父類接口調用方法執行子類重寫的方法即MyCollections.sort(list, new Comparator<Integer>() {子類重寫的方法})。if(result < 0){ //子類重寫方法中rerurn o1-o2保證result<0即o1后小,rerurn o2-o1保證result<0即o1后大。temp = list.get(j); //交換list.set(j, list.get(j + 1));list.set(j+1,temp);}}}} } package com.itheima05.collections; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator;public class CollectionsDemo02 {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list,5,3,2,4,1);MyCollections.sort(list, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1 - o2;}});System.out.println(list);} } package com.itheima05.collections; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.TreeSet;public class CollectionsDemo03 {public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>(); //ArrayList底層就是數組,數組和集合差不多。list.add(new Student("張三",20));list.add(new Student("李四",18));list.add(new Student("王五",22));/* Collections.sort(list, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age; //按年齡升序}});System.out.println(list);*///1111111111111111111111111111111111111111111111111111111111111111111111111111111111111 // sort(list) : 這個方法要求集合元素類型需要實現 Comparable接口 (Integer已實現,自定義類型必須手動實現) // Collections.sort(list); //如果就寫class Student不實現Comparable接口,這行會報錯 // System.out.println(list);//111111111111111111111111111111111111111111111111111111111111111111111111111111111111 TreeSet<Student> set = new TreeSet<>(); //TreeSet判定元素重復的原理:compare方法 : 兩數相減=0(不是hashcode和equals) //TreeSet底層紅黑樹(紅黑樹就是排序,左小右大),和哈希表無關,和Collections.sort一樣必須實現Comparable接口//Set重點是hashset,TreeSet底層和比較器完全一樣,TreeSet具備排序功能但效率不如hashset。TreeMap的key和TreeSet底層一樣set.add(new Student("張三",20));set.add(new Student("李四",18));set.add(new Student("王五",22));set.add(new Student("馬六",22)); //添不進去,因為compareTo比較的是age,不重復System.out.println(set);} }//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111 class Student implements Comparable<Student>{String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} @Overridepublic int compareTo(Student o) {return this.age - o.age; //升序,// this = o1,o = o2 } }
總結
以上是生活随笔為你收集整理的【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java7】练习:选角色,挑苹果,员工
- 下一篇: 【Java9】异常,finally,线程