文章目录

  • 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)

package com.itheima01.list;
import java.util.ArrayList;
/*
*   ArrayList: 数组
*       1. 最常用: 适合 查询需求比较多的场景
*       2. 原理: ArrayList扩容原理
*               ArrayList底层是数组,数组长度不可变,为什么ArrayList又可变呢? 因为数据迁移
*/
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. 底层数据结构: 双向链表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。

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)原理:元素不重复

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非常快就不用提前。

package com.itheima02.set;
import java.util.HashSet;
import java.util.Objects;
/*
*  HashSet: 判定重复元素:(明文地址【内】,hash值【外】,equals【名字】)。
*   内同-》重复不插,     内不同 外不同 默认e不同-》横插,       内不同 外同 e不同-》竖插
*
*  person类父类的Object: 1. hashcode:明文内存地址加密得到密文hash值
*(不同明文产生不同密文,刘亦菲明文即两个内存地址不一样,密文hash值基本不会相同,万一碰撞了,还有下面2进 行保障)
*           2. equals   == 比较真正内存地址
*
*      需求: 两个对象就算地址不同, 但是所有属性一一相同, 就认为是同一元素
*      解决: 重写hashcode和equals方法 -> 类中的所有属性,重写规范见文章: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是外部传入,转成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表的应用:元素不重复,效率高。

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:

package com.itheima01.map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class MapLoopDemo01 { //loop循环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. 根据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转化成 Set<Entry> setfor(Map.Entry<Integer,String> entry : entrySet){ // 2. 遍历这样的set, 取出每个entry//Entry是Map的内部接口,Map有很多Entry,Entry相当于Map属性一样。Map.是接口名直接调用//如果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实现类,因为快。
*       1. key不可以重复,但是value可以重复
*       2. key如何判定重复? 先判断hashcode ,再判断equals
*           Object: hashcode 和 equals 跟对象真正地址有关
*           重写了hashcode 和 equals,张三山东 覆盖 张三山西  新覆盖旧
*/
public class HashMapDemo {public static void main(String[] args) {//        method01();
//        method02(); //较method01交换了k和vnew LinkedHashSet<>(); //点进源码,底层是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<>(); //点进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);}
}



如下吴彦祖应该在第二个,存取无序,解决: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发给第二个。。。

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) {//数字写外面,外一次内一周,数字3和4种花拼接,并index标号依次从0对应到3,好按标号排序。            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集合中每个元素都放进list中//下面等同于上面 /*for (int i = 0; i < 54; i++) {  //0-53编号放进去list.add(i);}*///洗牌Collections.shuffle(list); //只能洗list集合//发牌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为数组名for (ArrayList<Integer> list : lists) {for (Integer number : list) {               String poker = map.get(number);  //从map中根据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数组工具类, 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相关推荐

  1. 常见的数据结构:栈 队列 数组 链表 红黑树——List集合 _ HashSet集合、可变参数 collections集合 Map集合

    2021-06-07复习java 一.常见的数据结构 栈(先进后出) 队列 数组 链表 红黑树 二.List集合_介绍&常用方法 ArrayList集合 Linkedlist集合 三.Hash ...

  2. Java集合常见数据结构-栈/队列/数组/链表/红黑树

    数组 链表 红黑树

  3. 存数组元素的个数_HashMap1.8之后为什么要采用数组+链表+红黑树的储存方式?

    HashMap概述 HashMap是基于Map接口实现的,采取(key,value)的储存方式.其中key和value可以为空,但是key不能重复.下面我们来详细解读一下HashMap的底层实现原理. ...

  4. Java--敲重点!JDK1.8 HashMap特性及底层数组+单链表+红黑树知识(建议收藏)

    ❤️‍大家好,我是贾斯汀!❤️‍ 学习目录 学习背景 HashMap特性 HashMap添加元素四步曲 前奏:HashMap如何添加一个元素? 第一步曲:根据key得到hashCode值 第二步曲:根 ...

  5. HashMap 实现原理及源码解析(jdk8 底层⽤的是数组+链表/红⿊树)

    本文会通过HashMap中的put方法为入口,进行源码解读,文章较长,需要耐心阅读 说明 /** */: 代表注释,区别于例子注释 egx::代表例子注释 解读前须知 源码主要关注4⼤点: 确定哈希桶 ...

  6. 算法高级(26)-在Java8中为什么要使用红黑树来实现的HashMap?

    一.前言 在jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度. 二.红黑树回顾 红黑树的英文是"Red-Black Tr ...

  7. 常见数据结构-栈-队列-数组-链表-哈希表

    数据结构   数据结构是计算机存储.组织数据的方式.是指相互之间存在一种或多种特定关系的数据元素的集合   通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 持续更新,学一个记一个- 栈 ...

  8. 对于一个采用字符数组存放的字符串str,设计一个递归算法StrLength(char *str)求其字符个数(长度)。递归求字符串长度

    递归求字符串长度,需要的就是将数组看成指针,一步一步走下去 int StrLength(char *str) {char *p=str;if(*p=='\0') return 0;else{retur ...

  9. Java笔记整理五(Iterator接口,泛型,常见数据结构(栈,队列,数组,链表,红黑树,集合),jdk新特性,异常,多线程,Lambda表达式)

    Java笔记整理五 1.1Iterator接口 Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象 ...

最新文章

  1. 【温故知新】CSS学习笔记(样式表)
  2. java计数循环及小技巧
  3. Zoom的Web客户端与WebRTC有何不同?
  4. 计算机通信事业单位专业知识点,事业单位计算机专业知识招考大纲
  5. linux 内存越界判断_虚拟内存 和 page fault 的解释
  6. ae saber插件_【AE插件】 用于做动画制作/设计的五个免费插件 非常好用
  7. docker的php教程https,Docker搭建php环境教程详解
  8. android版本下载地址 http,Android ADT下载地址(含各版本)
  9. 瓦楞机自动排单技术收藏
  10. 电脑重装系统后c盘数据能恢复吗?
  11. 樊登读书会终身成长读后感_《终身成长》读书笔记
  12. tableViewCell、collectionViewCell、组头组尾等总结
  13. 面试阿里被问的哑口无言,原来我……
  14. Python有道智云API图片文字识别
  15. 【LOJ2867】「IOI2018」高速公路收费
  16. 杭州软件测试人员工资水平,杭州软件测试工资待遇如何?
  17. 为什么电脑浏览器显示时钟快了_xp打开网页提示“你的时钟慢了”的原因及解决方法...
  18. swift 代码加载xib storyboard
  19. 2022中国数据库产业排行榜
  20. 图谱实战 | 华农夏静波:深层语义知识图谱在药物重定位中的应用

热门文章

  1. YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!)
  2. DataUml Design 教程6-DataUML Design 1.1版本号正式公布(支持PD数据模型)
  3. Wix学习整理(2)——HelloWorld安装添加UI
  4. 我的.net程序在linux上运行起啦
  5. 16、Windows API 服务
  6. db2 两个结构相同的表_从两个工作表提取数据记录,并显示相同记录的报告
  7. 每日程序C语言25-查找100以内的素数
  8. 台式电脑怎么连接手机热点_电脑搜不到手机热点 为什么搜不到手机热点
  9. Java黑皮书课后题第7章:*7.30(模式识别:四个连续相等的数)编写下面的方法,测试某数组是否有四个连续相同值的数。编写测试程序,提示用户输入一个整数列表,调用方法看是否有4个连续且相等的数
  10. Java黑皮书课后题第3章:**3.22(几何:点是否在圆内)编写程序,提示用户输入一个点(x,y),然后检查这个点是否在以(0,0)为圆心、半径为10的圆内