日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet

發(fā)布時間:2024/4/24 java 68 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1.堆棧/隊列/數(shù)組/鏈表:數(shù)據(jù)結(jié)構(gòu)即計算機(jī)組織管理數(shù)據(jù)的方式,堆棧指的是內(nèi)存圖中的棧,不是堆
  • 2.紅黑樹:二查,二查平,二查平1倍
  • 3.List子接口:集合,IndexOutOfBoundsException
  • 4.ArrayList的擴(kuò)容原理:Stringbuild默認(rèn)長度=16,擴(kuò)容2倍
  • 5.LinkedList:push堆棧
  • 6.set子接口:單例=keySet
  • 7.Object類的hashcode方法:對象的真正的內(nèi)存地址(無限種)->哈希碼 (43億不到的可能)。極端下多個明文 -> 同一密文 (哈希碰撞)。打印對象,.toString(),.hashCode()
  • 8.String類的hashcode方法:a97,碰撞
  • 9.哈希表(HashSet)原理:元素不重復(fù)
  • 10.linkedHashset和Hashset區(qū)別:A a = new A(){},coll.iterator().hasNext()
  • 11.Map:Map和Collection是并列關(guān)系,Map.Entry < Integer,String > 是數(shù)據(jù)類型
  • 12.內(nèi)部接口:除了Inner訪問受限于Outer,這兩各自獨立
  • 13.統(tǒng)計字符出現(xiàn)個數(shù):.containsKey(.charAt)
  • 14.debug:斷點/單點/高級調(diào)試
    • 14.1 單步調(diào)試: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 高級調(diào)試:
      • 15.2.1 跨斷點調(diào)試
      • 15.2.2 查看斷點
      • 15.2.3 設(shè)置變量值
  • 16.斗地主:list.addAll(set)
  • 17.Collections類和TreeSet:return o1-o2是升序
      • 17.1 自定義MyCollections類來模擬完成addAll()和sort()方法


1.堆棧/隊列/數(shù)組/鏈表:數(shù)據(jù)結(jié)構(gòu)即計算機(jī)組織管理數(shù)據(jù)的方式,堆棧指的是內(nèi)存圖中的棧,不是堆



如下查詢慢:知道張三在哪,不能馬上知道王五在哪,挨個查。如下增刪雖然不用整個動(如刪除李四,只需要將箭頭指向王五就行),但是還是要先查找到再刪除,效率還是慢。但是直接刪除張三或馬六頭尾元素快。

2.紅黑樹:二查,二查平,二查平1倍

二叉樹:每個節(jié)點最多兩個子節(jié)點。查找樹:左小右大(二分法)。平衡樹:左右盡量相等(一邊的節(jié)點層次不會超過另一邊的兩倍)。二查平1倍:紅黑樹(數(shù)組和鏈表折中方案)。

二叉搜索樹BST(二查):插入或查詢一節(jié)點時,樹的每一行只需要和這一行的一個節(jié)點比較(因為左小右大),復(fù)雜度完全依賴樹深度。樹的行數(shù)即高度=logn【n為節(jié)點總數(shù),2的樹行數(shù)次方為n】,BST讀和寫的復(fù)雜度都為logn。

有序數(shù)組:查找時用二分查找法(和BST像),時間復(fù)雜度也為logn。有序數(shù)組查詢最差情況logn,而當(dāng)BST為單邊時(最差情況),BST查詢和插入都為o(n)。為什么很多情況下用BST,而不是有序數(shù)組二分查找?因為有序數(shù)組查找用二分查找logn,但是插入(不是查)要移動,插入時間復(fù)雜度為o(n)。

BST很少在語言內(nèi)部數(shù)據(jù)結(jié)構(gòu)存儲里用(因為下面直線情況),自平衡二叉樹AVL(二查平)是BST(二查)的繼承優(yōu)化:左子樹和右子樹都是平衡二叉樹,而且左子樹和右子樹深度之差絕對值不會超過1(左旋和右旋),AVL讀和寫的復(fù)雜度最差情況都為O(logn)。

AVL平衡左右子樹相差1,這個條件很苛刻,導(dǎo)致很多情況下都不滿足這個平衡條件,需要旋轉(zhuǎn)變換,變換的話需要浪費時間。紅黑樹(二平查1倍)平衡條件更加寬松些左右深度差一倍即> = 節(jié)點數(shù)相同,< = 節(jié)點數(shù)差一倍(因為紅節(jié)點的子節(jié)點必須為黑即黑紅相間)。葉子節(jié)點(最后一個)和null節(jié)點都為黑節(jié)點

這樣寬松條件導(dǎo)致我們在插入節(jié)點時候變化更少的,所以紅黑樹寫的性能會高一些,所以treemap/hashmap底層采用紅黑樹(BST會變直線,AVL左右只能差1)。

如下是紅黑樹的插入變色流程:最上面根節(jié)點必須為黑,插入節(jié)點(為葉子節(jié)點)必為紅節(jié)點(看插入節(jié)點的父節(jié)點和父節(jié)點的兄弟節(jié)點即叔節(jié)點)。null節(jié)點算葉子節(jié)點即黑節(jié)點,當(dāng)前插入的003是爺爺節(jié)點001的右右。

如下左旋+變色。

3.List子接口:集合,IndexOutOfBoundsException

package com.itheima01.list; import java.util.ArrayList; import java.util.List; /*Collection子接口:List1. List的特點:重索序1. 有先后順序:元素存儲的順序和取出的順序相同2. 具有整數(shù)索引,就是下標(biāo)3. 允許重復(fù)元素2. List的方法(帶索引)(List特有的,共有的在Collection講過)1. add(int index, E element) :往索引位置添加一個元素1. Java中的 三個越界異常1. IndexOutOfBoundsException 集合2. ArrayIndexOutOfBoundsException 數(shù)組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 : 數(shù)組索引越界String str = "abc"; // 字符串底層也是數(shù)組// char c = str.charAt(3); //索引0,1,2 // System.out.println(c); //StringIndexOutOfBoundsException:字符串索引越界} }

4.ArrayList的擴(kuò)容原理:Stringbuild默認(rèn)長度=16,擴(kuò)容2倍

ArrayList底層是存Object數(shù)組,擴(kuò)容新建一個長度為原來1.5倍新數(shù)組(空)。

如下10進(jìn)制的4就是2進(jìn)制的0100(8421),3/2=1,ArrayList.java源碼中出現(xiàn)左右移(二進(jìn)制右移一位相當(dāng)于十進(jìn)制/2)。

package com.itheima01.list; import java.util.ArrayList; /* * ArrayList: 數(shù)組 * 1. 最常用: 適合 查詢需求比較多的場景 * 2. 原理: ArrayList擴(kuò)容原理 * ArrayList底層是數(shù)組,數(shù)組長度不可變,為什么ArrayList又可變呢? 因為數(shù)據(jù)遷移 */ public class ArrayListDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("xx");System.out.println(3 >> 1); // 1 //除2取整System.out.println(4 >> 1); // 2System.out.println(10 >> 1); // 5System.out.println(3 << 2); //12 //3*2*2,左移2位} }

5.LinkedList:push堆棧

package com.itheima01.list; import java.util.LinkedList; /*LinkedList特點1. 底層數(shù)據(jù)結(jié)構(gòu): 雙向鏈表2. 查詢速度慢,增刪快(增刪需求多而且增刪首尾用LinkedList)3. 特有方法(不能使用多態(tài),父類不能調(diào)子類特有方法)1. addFirst 元素添加在鏈表開頭2. addLast(add相同) 元素添加在鏈表結(jié)尾3. getFirst 獲取鏈表開頭4. getLast 獲取鏈表結(jié)尾5. removeFirst 移除并返回鏈表開頭6. removeLast 移除并返回鏈表結(jié)尾//下面兩個不需要掌握7. pop 從此列表所表示的堆棧處彈出一個元素(最頂部元素彈出,removeFirst)8. push 將元素推入此列表所表示的堆棧(元素存儲到集合頂部,addFirst) */ public class LinkedListDemo {public static void main(String[] args) { // method01();LinkedList<String> list = new LinkedList<>();list.add("張三"); // 是鏈表,不是按堆棧結(jié)構(gòu)添加元素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 //元素不可重復(fù)System.out.println(set);//[李四,張三,王五] //存取不保證順序} }

7.Object類的hashcode方法:對象的真正的內(nèi)存地址(無限種)->哈希碼 (43億不到的可能)。極端下多個明文 -> 同一密文 (哈希碰撞)。打印對象,.toString(),.hashCode()

package com.itheima03.hash; /* * Object類有一個方法: int hashCode() : 返回該對象的哈希碼值。 * 1. 原理: 將對象的真正的內(nèi)存地址(明文) 進(jìn)行 哈希算法 加密之后產(chǎn)生的 哈希碼值(密文) * 2. 加密 : * 明文 : 大家都看的懂東西 I love you * 密文 : 明文經(jīng)過加密算法變成密文 J mpwf zpv * 加密算法: 數(shù)學(xué) (凱撒加密: 字母按字母表右移動一位) * 破解: 頻率分析法 (e i -> d h),截獲大量數(shù)據(jù)進(jìn)行大數(shù)據(jù)分析e,i出現(xiàn)頻率最高,密文中出現(xiàn)最多的是d,h * * 哈希算法: 公開 * 基本保證 一個明文 -> 一個密文 不同明文不同的密文 * 告訴你算法,告訴你密文, 算不出明文 * * 3. 源碼: public native int hashCode(); 本地方法 * native(本地關(guān)鍵字) 修飾的方法沒有java方法體 (方法實現(xiàn)在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 // 上面兩個打印結(jié)果都一樣 // 如下內(nèi)存地址: 16進(jìn)制哈希碼值14ae5a5 和下面10進(jìn)制相等System.out.println(p.hashCode()); // 10進(jìn)制: 21685669} } class Person{ }

8.String類的hashcode方法:a97,碰撞

String s1 = “abc”,如下h就是hash值(只看最后一個h),b是98,c是99。

package com.itheima03.hash; // String類重寫了Object的hashcode方法 (31算法) public class StringHashCodeDemo {public static void main(String[] args) {String s1 = "abc";String s2 = "acD";String s3 = "重地";String s4 = "通話";System.out.println(s1.hashCode());//96354System.out.println(s2.hashCode());//96354 //和上面哈希碰撞System.out.println(s3.hashCode()); //1179395System.out.println(s4.hashCode()); //1179395} }

9.哈希表(HashSet)原理:元素不重復(fù)

hashcode(密文)為HashSet(HashSet底層數(shù)據(jù)結(jié)構(gòu)是hash表)做鋪墊。如下三個abc字符串都為96354。問題:HashSet如何判定這個元素是否跟已存在的元素是重復(fù)即如下[重地,通話,abc,acD]?Set不存重復(fù)元素。S3因為是new出來的,和S1,S2明文即真正的內(nèi)存地址不一樣。

下面S1,S4,S5,S6都是不重復(fù)元素。豎:暗文或暗文%16同(因為數(shù)組長度為16),equal不一樣。橫:明文和暗文和equal都不一樣。HashSet是效率最高的set且元素不重復(fù),同一鏈表(豎)hashcode一樣,但是鏈表如果太長查詢慢,所以假如同一hash值(hashcode)碰撞了8次,鏈表重構(gòu)為紅黑樹。

同一鏈表上都hash碰撞,數(shù)組的第一個位置余數(shù)=0,第二個位置余數(shù)=1。。。16的容量為什么到16*0.75=12就擴(kuò)容了?再哈希rehash(余數(shù)重新算)這段時間內(nèi),16沒滿,我還有的用,如果rehash非常快就不用提前。

package com.itheima02.set; import java.util.HashSet; import java.util.Objects; /* * HashSet: 判定重復(fù)元素:(明文地址【內(nèi)】,hash值【外】,equals【名字】)。 * 內(nèi)同-》重復(fù)不插, 內(nèi)不同 外不同 默認(rèn)e不同-》橫插, 內(nèi)不同 外同 e不同-》豎插 * * person類父類的Object: 1. hashcode:明文內(nèi)存地址加密得到密文hash值 *(不同明文產(chǎn)生不同密文,劉亦菲明文即兩個內(nèi)存地址不一樣,密文hash值基本不會相同,萬一碰撞了,還有下面2進(jìn) 行保障) * 2. equals == 比較真正內(nèi)存地址 * * 需求: 兩個對象就算地址不同, 但是所有屬性一一相同, 就認(rèn)為是同一元素 * 解決: 重寫hashcode和equals方法 -> 類中的所有屬性,重寫規(guī)范見文章:https://blog.csdn.net/weixin_43435675/article/details/112604089 */ public class HashSetDemo02 {public static void main(String[] args) {HashSet<Person> set = new HashSet<>();set.add(new Person("高圓圓",18));set.add(new Person("劉亦菲",19));set.add(new Person("劉亦菲",19));//Person類繼承Object類,new新地址System.out.println(set); } } class Person{String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic boolean equals(Object o) { //alt+insert選equals()and hashCode() //每個屬性一一比對if (this == o) return true;if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; //o是外部傳入,轉(zhuǎn)成personreturn age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age); //工具類Objects.java中hash方法中hashCode方法就是31算法,也是逐一遍歷}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';} }

沒有重寫Person類的hashcode和equals方法。

如下重寫…如下就是hash表的應(yīng)用:元素不重復(fù),效率高。

10.linkedHashset和Hashset區(qū)別: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<>(); //向上轉(zhuǎn)型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接口類型 變量 = 其實現(xiàn)類對象 (多態(tài)的向上轉(zhuǎn)型)/* Iterator<String> it = coll.iterator(); //Collection即coll是接口,接口調(diào)用方法執(zhí)行子類ArrayList重寫的iterator()while(it.hasNext()){String name = it.next();System.out.println(name); //張三 張三2 張三3}*/// while(coll.iterator().hasNext()){ //不能這樣把it換了鏈?zhǔn)骄幊?#xff0c;原因如下圖 // String name = coll.iterator().next(); // System.out.println(name); // }}//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111public static void method01(){MyClass mc = new MyClass();A a = mc.test(); //右邊返回必然是A接口實現(xiàn)類對象即向上轉(zhuǎn)型,不需要new //上行等同于Iterator<String> it = coll.iterator(); 不一定需要看到new A a2 = new A() { //java中對象不一定看到new才放心 //new一個實現(xiàn)接口的匿名內(nèi)部類A,使用{}具體實現(xiàn)接口 @Overridepublic void show() {}} ;} } interface A{void show(); } class MyClass{public A test(){ //返回A接口,不寫void // A a = new A(){}; //匿名內(nèi)部類 // return a;return new A() { //下面等同于上面兩行,return A接口的子類對象@Overridepublic void show() {}};} }

11.Map:Map和Collection是并列關(guān)系,Map.Entry < Integer,String > 是數(shù)據(jù)類型

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,如果存儲了重復(fù)的鍵,返回被覆蓋之前的值3. get:通過鍵,取出鍵對應(yīng)的值1. V get(K),傳遞鍵,返回對應(yīng)的值2. 如果集合中沒有這個鍵,返回null4. remove:移除鍵值對1. V remove(K),傳遞鍵,移除這個鍵值對2. 返回值:移除之前的值(無此鍵,則返回null)5. keySet: 將集合中所有的鍵,存儲到Set集合中6. entrySet:獲取到Map集合中所有的鍵值對存入Set接中7. size:獲取map集合的大小 * Map: * 1. key不可以重復(fù) * 2. value可以重復(fù) * 如果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);//馬六//根據(jù)key刪除key-valuemap.remove(3);System.out.println(map);System.out.println(map.size()); //3,幾個k} }

如下key不可重復(fù),所以放到set集合(單例)。如下兩種遍歷方式都涉及set:

package com.itheima01.map; import java.util.HashMap; import java.util.Map; import java.util.Set;public class MapLoopDemo01 { //loop循環(huán)public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();map.put(1,"張三");map.put(2,"李四");map.put(3,"王五"); Set<Integer> keySet = map.keySet(); //1.把key這一列取出來放到set集合中 for (Integer key : keySet) { //2.遍歷這個set集合,取出每個key。keySet.for回車 String value = map.get(key); //3. 根據(jù)key獲取valueSystem.out.println(key + "->" + value);}} }

package com.itheima01.map; import java.util.HashMap; import java.util.Map; import java.util.Set;public class MapLoopDemo02 {public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();map.put(1,"張三");map.put(2,"李四");map.put(3,"王五");Set<Map.Entry<Integer,String>> entrySet = map.entrySet(); // 1. 把map轉(zhuǎn)化成 Set<Entry> setfor(Map.Entry<Integer,String> entry : entrySet){ // 2. 遍歷這樣的set, 取出每個entry//Entry是Map的內(nèi)部接口,Map有很多Entry,Entry相當(dāng)于Map屬性一樣。Map.是接口名直接調(diào)用//如果import java.util.Map.Entry,則Map.Entry可換成Entry Integer key = entry.getKey(); //3. 從這個鍵值對中,取鍵,再取值String value = entry.getValue();System.out.println(key + "--" + value);}} }


package com.itheima03.impl; import java.util.*; /* * HashMap是最常用的map實現(xiàn)類,因為快。 * 1. key不可以重復(fù),但是value可以重復(fù) * 2. key如何判定重復(fù)? 先判斷hashcode ,再判斷equals * Object: hashcode 和 equals 跟對象真正地址有關(guān) * 重寫了hashcode 和 equals,張三山東 覆蓋 張三山西 新覆蓋舊 */ public class HashMapDemo {public static void main(String[] args) { // method01(); // method02(); //較method01交換了k和vnew LinkedHashSet<>(); //點進(jìn)源碼,底層是LinkedHashMapnew TreeSet<>(); //TreeMapnew HashSet<>(); //HashMap//如下有序存取LinkedHashMap<Person,String> map = new LinkedHashMap<>();map.put(new Person("張三",18),"山西");map.put(new Person("吳彥祖",20),"福州");map.put(new Person("李四",19),"廣東"); // map.put(new Person("張三",18),"山東");Set<Person> keySet = map.keySet();for (Person key : keySet) {String value = map.get(key);System.out.println(key + "---" + value);}}private static void method02() {HashMap<Person,String> map = new HashMap<>();map.put(new Person("張三",18),"山西"); //key=Person 自定義類型map.put(new Person("吳彥祖",20),"福州");map.put(new Person("李四",19),"廣東");map.put(new Person("張三",18),"山東"); //new出來地址不同Set<Person> keySet = map.keySet();for (Person key : keySet) {String value = map.get(key);System.out.println(key + "---" + value);}// HashSet<Object> set = new HashSet<>(); //點進(jìn)HashSet看源碼 //HashSet【collection接口】的底層是HashMap【Map接口】 ,只不過hashset只使用了HashMap key這一列,value這一列不用}private static void method01() { HashMap<String, Person> map = new HashMap<>();map.put("1號",new Person("張三",18)); //value=Person 自定義類型map.put("2號",new Person("李四",19));map.put("3號",new Person("李四",19));map.put("1號",new Person("王五",20)); //System.out.println(map);Set<Map.Entry<String,Person>> entrySet = map.entrySet();for (Map.Entry<String, Person> entry : entrySet) {String key = entry.getKey();Person value = entry.getValue();System.out.println(key + "-" + value);}} }class Person{String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {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);}@Overridepublic int hashCode() {return Objects.hash(name, age);} }



如下吳彥祖應(yīng)該在第二個,存取無序,解決:HashMap換成LinkedHashMap。

12.內(nèi)部接口:除了Inner訪問受限于Outer,這兩各自獨立

package com.itheima02.inner; import java.lang.reflect.Field; import java.util.Date; import com.itheima02.inner.Outer.Inner; /* * inner class : 訪問受限, 受限于外部類 * 有兩個包是不用導(dǎo)入:1. java.lang (String,Object) * 2. 當(dāng)前類所在的包 * 1和2的子包都要導(dǎo)(如內(nèi)部接口就在當(dāng)前包的子包下) */ public class InnerDemo {public static void main(String[] args) { // new Date()new String("");new Object(); // new Field(); //java.lang包的子包,要導(dǎo)包} }//1111111111111111111111111111111111111111111111111111111111111111111111111111111111111 interface Outer{//public static final //因為Outer是接口,所以不能實例化,只能接口.。所以final讓I變?yōu)槌A?#xff0c;static讓I可用接口名.直接調(diào)用int I = 1;//public abstractvoid outerMethod();//new外部類對象不需要new內(nèi)部類對象,同理實現(xiàn)Outer接口不需要實現(xiàn)Inner接口//public static //外部接口不能創(chuàng)建實例來調(diào)用,所以接口名調(diào)用,所以靜態(tài)。上面Map.Entry即外接口.內(nèi)接口(Entry是Map的內(nèi)接口)interface Inner{ void innerMethod();} } class A implements Outer{ //不需要實現(xiàn)Inner@Overridepublic void outerMethod() {} } class B implements Outer.Inner{@Overridepublic void innerMethod() {} } class C implements Outer,Inner{//上面導(dǎo)過包了,Inner不用寫成Outer.Inner@Overridepublic void outerMethod() {}@Overridepublic void innerMethod() {} }

13.統(tǒng)計字符出現(xiàn)個數(shù):.containsKey(.charAt)

統(tǒng)計字符串中:大小寫字母及數(shù)字字符個數(shù):https://blog.csdn.net/weixin_43435675/article/details/107434867

package com.itheima03.impl; import java.util.HashMap; /* * 需求: 計算一個字符串中每個字符出現(xiàn)次數(shù)。 * 0. 弄一個Map : 記錄 字符=次數(shù) (就像畫正字選票) * char int * 1. 遍歷這個字符串,取出每個字符 * 2. 判斷Map中是否存在這個字符-> boolean containsKey(Object key) 如果此映射包含指定鍵的映射關(guān)系,則返回 true。 * 3. 有: 在對應(yīng)的次數(shù)+1 。沒有 : 字符char=1 存進(jìn)去 */ 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); //相應(yīng)索引訪問到相應(yīng)字符boolean result = map.containsKey(c); //一開始map為空,下面依次寫進(jìn)去if(result){ // 存在,次數(shù)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:斷點/單點/高級調(diào)試

先設(shè)斷點再點擊如下進(jìn)入調(diào)試。


紅色的箭頭指向的是現(xiàn)在調(diào)試程序停留的代碼行:方法 f2() 中,程序的第11行。紅色箭頭懸停的區(qū)域是程序的方法調(diào)用棧區(qū)。在這個區(qū)域中顯示了程序執(zhí)行到斷點處所調(diào)用過的所有方法,越下面的方法被調(diào)用的越早。

14.1 單步調(diào)試:over,into,out

14.1.1 step over


點擊紅色箭頭指向的按鈕,程序向下執(zhí)行一行(如果當(dāng)前行有方法調(diào)用,這個方法將被執(zhí)行完畢返回,然后到下一行)。

14.1.2 step into


點擊紅色箭頭指向的按鈕,程序向下執(zhí)行一行。如果該行有自定義方法,則運行進(jìn)入自定義方法(不會進(jìn)入官方類庫的方法)。具體步驟如下:在自定義方法發(fā)f1()處設(shè)置斷點,執(zhí)行調(diào)試。

點擊如下。

14.1.3 Force step into


該按鈕在調(diào)試的時候能進(jìn)入任何方法。

14.1.4 step out


如果在調(diào)試的時候你進(jìn)入了一個方法(如f2()),并覺得該方法沒有問題,你就可以使用stepout跳出該方法,返回到該方法被調(diào)用處的下一行語句。值得注意的是,該方法已執(zhí)行完畢。

14.1.5 Drop frame


點擊該按鈕后,你將返回到當(dāng)前方法的調(diào)用處(如上圖,程序會回到main()中)重新執(zhí)行,并且所有上下文變量的值也回到那個時候。只要調(diào)用鏈中還有上級方法,可以跳到其中的任何一個方法。

15.2 高級調(diào)試:

15.2.1 跨斷點調(diào)試

設(shè)置多個斷點,開啟調(diào)試。想移動到下一個斷點,點擊如下圖:

程序?qū)⑦\行一個斷點到下一個斷點之間需要執(zhí)行的代碼。如果后面代碼沒有斷點,再次點擊該按鈕將會執(zhí)行完程序。

15.2.2 查看斷點


點擊箭頭指向的按鈕,可以查看你曾經(jīng)設(shè)置過的斷點并可設(shè)置斷點的一些屬性。

箭頭1指向的是你曾經(jīng)設(shè)置過的斷點,箭頭2可以設(shè)置條件斷點(滿足某個條件的時候,暫停程序的執(zhí)行,如 c==97)。結(jié)束調(diào)試后,應(yīng)該在箭頭1處把所設(shè)的斷點刪除(選擇要刪除的斷點后,點擊上方的紅色減號)。

15.2.3 設(shè)置變量值


調(diào)試開始后,在紅箭頭指向的區(qū)域可以給指定的變量賦值(鼠標(biāo)左鍵選擇變量,右鍵彈出菜單選擇setValue…)。這個功能可以更加快速的檢測你的條件語句和循環(huán)語句。

16.斗地主:list.addAll(set)

package com.itheima04.Poker; import java.util.ArrayList; import java.util.Collections; // 寫一個規(guī)則: 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發(fā)給第一個,13發(fā)給第二個。。。

package com.itheima04.Poker; import java.util.*;class PokerDemo {public static void main(String[] args) { HashMap<Integer, String> map = new HashMap<>(); //key=編號, value=牌面String[] colors = {"?","?","?","?"};String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};int index=0;for (String number : numbers) {//數(shù)字寫外面,外一次內(nèi)一周,數(shù)字3和4種花拼接,并index標(biāo)號依次從0對應(yīng)到3,好按標(biāo)號排序。 for (String color : colors) {String poker = color + number;map.put(index,poker);index++;}} // System.out.println(map); //{0=黑桃3,1=紅心3,2=梅花3,...}map.put(52,"小?");map.put(53,"大?"); Set<Integer> set = map.keySet(); //0-53ArrayList<Integer> list = new ArrayList<>();list.addAll(set); //將set集合中每個元素都放進(jìn)list中//下面等同于上面 /*for (int i = 0; i < 54; i++) { //0-53編號放進(jìn)去list.add(i);}*///洗牌Collections.shuffle(list); //只能洗list集合//發(fā)牌ArrayList<Integer> p1 = new ArrayList<>();ArrayList<Integer> p2 = new ArrayList<>();ArrayList<Integer> p3 = new ArrayList<>();ArrayList<Integer> dp = new ArrayList<>();for (int i = 0; i < list.size(); i++) { //list里全是編號Integer number = list.get(i);int mod = i % 3;if(i < 3){dp.add(number);}else if(mod == 1){p1.add(number);}else if(mod == 2){p2.add(number);}else if(mod == 0){p3.add(number);}}//排序(Integer:從小到大)Collections.sort(p1);Collections.sort(p2);Collections.sort(p3);Collections.sort(dp); // lookPoker(map,p1); //因為list即p里都是編號,所以還需要map // lookPoker(map,p2); // lookPoker(map,p3); // lookPoker(map,dp);lookPoker(map,p1,p2,p3,dp);}private static void lookPoker(HashMap<Integer, String> map, ArrayList<Integer>... lists) { //lists為數(shù)組名for (ArrayList<Integer> list : lists) {for (Integer number : list) { String poker = map.get(number); //從map中根據(jù)number 取出 pokerSystem.out.print(poker + "\t");}System.out.println();}} // private static void lookPoker(HashMap<Integer,String> map,ArrayList<Integer> list){ // for(Integer number : list){ // String poker = map.get(number); // System.out.print(poker+"\t"); // } // System.out.println(); // } }

17.Collections類和TreeSet:return o1-o2是升序

package com.itheima05.collections; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /*Arrays數(shù)組工具類, Objects對象工具類(命名規(guī)則最后+s)- java.utils.Collections是集合工具類,用來對集合進(jìn)行操作。 常用方法如下: - public static void shuffle(List<?> list):打亂集合順序。 - public static <T> void sort(List<T> list):將集合中元素按照默認(rèn)規(guī)則排序。 - public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規(guī)則排序。 */ public class CollectionsDemo01 {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>(); //Integer源碼實現(xiàn)了Comparable接口 Collections.addAll(list,5,3,2,4,1); //System.out.println(list); //[3,4,5,1,2]// Collections.sort(list); // 默認(rèn): 升序// 如下第二個參數(shù)類型是Comparator接口,必須傳入接口實現(xiàn)類對象:new Comparator...后面全是匿名內(nèi)部類Collections.sort(list, new Comparator<Integer>() { // 自定義升降序規(guī)則 , 任何排序都是兩兩比較 @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排序。//注意: 第二個參數(shù)是接口,必須傳入接口實現(xiàn)類(這將形成多態(tài): 父接口引用調(diào)用方法執(zhí)行的是子類重寫方法)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相鄰比較,父類接口調(diào)用方法執(zhí)行子類重寫的方法即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底層就是數(shù)組,數(shù)組和集合差不多。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) : 這個方法要求集合元素類型需要實現(xiàn) Comparable接口 (Integer已實現(xiàn),自定義類型必須手動實現(xiàn)) // Collections.sort(list); //如果就寫class Student不實現(xiàn)Comparable接口,這行會報錯 // System.out.println(list);//111111111111111111111111111111111111111111111111111111111111111111111111111111111111 TreeSet<Student> set = new TreeSet<>(); //TreeSet判定元素重復(fù)的原理:compare方法 : 兩數(shù)相減=0(不是hashcode和equals) //TreeSet底層紅黑樹(紅黑樹就是排序,左小右大),和哈希表無關(guān),和Collections.sort一樣必須實現(xiàn)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)); //添不進(jìn)去,因為compareTo比較的是age,不重復(fù)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 } }


總結(jié)

以上是生活随笔為你收集整理的【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。