1、能够了解红黑树
2、能够掌握HashSet集合的特点以及使用(特点以及使用,哈希表数据结构)
3、能够掌握Map集合的特点以及使用(特点,常见方法,Map集合的遍历)
4、能够掌握HashMap集合的特点以及使用
5、能够掌握TreeMap集合的特点以及使用
1.什么是红黑树
平衡二叉B树,每一个节点可以是红或者黑,红黑树不是 高度平衡 的,它的平衡是通过"自己的红黑规则"进行实现的。
添加节点时,默认为红色,效率高
(旋转之后,根据规则验证是否是红黑树,总结红黑树添加节点的规则)
(共3点)
1.案例需求
代码实现
学生类
public class Student implements Comparable { private String name; private int chinese; private int math; private int english; public Student() { } public Student(String name, int chinese, int math, int english) { this.name = name; this.chinese = chinese; this.math = math; this.english = english; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChinese() { return chinese; } public void setChinese(int chinese) { this.chinese = chinese; } public int getMath() { return math; } public void setMath(int math) { this.math = math; } public int getEnglish() { return english; } public void setEnglish(int english) { this.english = english; } public int getSum() { return this.chinese + this.math + this.english; } @Override public int compareTo(Student o) { // 主要条件: 按照总分进行排序 int result = o.getSum() - this.getSum(); // 次要条件: 如果总分一样,就按照语文成绩排序 result = result == 0 ? o.getChinese() - this.getChinese() : result; // 如果语文成绩也一样,就按照数学成绩排序 result = result == 0 ? o.getMath() - this.getMath() : result; // 如果总分一样,各科成绩也都一样,就按照姓名排序 result = result == 0 ? o.getName().compareTo(this.getName()) : result; return result; }}
测试类
public class TreeSetDemo { public static void main(String[] args) { //创建TreeSet集合对象,通过比较器排序进行排序 TreeSet ts = new TreeSet(); //创建学生对象 Student s1 = new Student("jack", 98, 100, 95); Student s2 = new Student("rose", 95, 95, 95); Student s3 = new Student("sam", 100, 93, 98); //把学生对象添加到集合 ts.add(s1); ts.add(s2); ts.add(s3); //遍历集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getEnglish() + "," + s.getSum()); } }}
2.TreeSet原理
1.什么是HashSet(HashSet的特点)
2.HashSet使用-存储字符串并遍历
package com.itheima.myhashset;import java.util.HashSet;import java.util.Iterator;/** * 添加字符串并进行遍历 */public class HashSetDemo1 { public static void main(String[] args) { HashSet hs = new HashSet<>(); hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("java"); hs.add("java"); hs.add("java"); hs.add("java"); hs.add("java"); Iterator it = hs.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } System.out.println("============================="); for (String s : hs) { System.out.println(s); } }}
1.什么是哈希值
是JDK根据对象的地址或者属性值,算出来的int类型的整数
2.如何获取对象中的Hash值
Object类中有一个方法: public int hashCode():根据对象的地址值计算出来的哈希值
3.哈希值的特点
1.同种一对象多次调用hashCode方法返回值是一样的
2.不同对象hashCode方法返回值不一样
重写的目的是计算对象哈希值时,按属性值来计算,因此只要属性值相同,不同对象的hashCode方法返回值是一样的
package com.itheima.myhashset;/** * 计算哈希值 */public class HashSetDemo2 { public static void main(String[] args) { Student s1 = new Student("xiaozhi",23); Student s2 = new Student("xiaomei",22); //因为在Object类中,是根据对象的地址值计算出来的哈希值。 System.out.println(s1.hashCode());//1060830840 System.out.println(s1.hashCode());//1060830840 System.out.println(s2.hashCode());//2137211482 }}
Student类
package com.itheima.myhashset;public class Student { private String name; private int age; public Student() { } public Student(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; } //我们可以对Object类中的hashCode方法进行重写 //在重写之后,就一般是根据对象的属性值来计算哈希值的。 //此时跟对象的地址值就没有任何关系了。 @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; }}
哈希表=数组 + 链表
(共两点)
1.HashSet 在JDK1.8之后的原理
2.HashSet 在JDK1.8版本的存储流程
代码实现
测试类
public class HashSetDemo2 { public static void main(String[] args) { //HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法 HashSet hashSet = new HashSet<>(); Student s1 = new Student("xiaohei",23); Student s2 = new Student("xiaohei",23); Student s3 = new Student("xiaomei",22); hashSet.add(s1); hashSet.add(s2); hashSet.add(s3); for (Student student : hashSet) { System.out.println(student); } }}
学生类
package com.itheima.myhashset;public class Student { private String name; private int age; public Student() { } public Student(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; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Student student = (Student) o; if (age != student.age) { return false; } return name != null ? name.equals(student.name) : student.name == null; } //我们可以对Object类中的hashCode方法进行重写 //在重写之后,就一般是根据对象的属性值来计算哈希值的。 //此时跟对象的地址值就没有任何关系了。 @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; }}
(共3点)
1.什么是Map集合【记忆】
Map集合又称为双列集合,双列集合中元素的内容是成对的
2.Map集合的特点 【记忆】
键不能重复,值可以重复
键与值之间是一一对应的关系
(键+值)这个整体我们称之为"键值对"或"键值对对象",在Java中又叫"Entry对象"
3.如何使用Map集合
1.Map集合格式
interface Map K:键的类型;V:值的类型
2.如何创建Map集合对象
Map map = new HashMap();//使用具体实现类,采用多态形式创建
4.使用Map集合存储学生学号和姓名
package com.itheima.mapdemo1;import java.util.HashMap;import java.util.Map;/** * Map的基本使用 */public class MyMap1 { public static void main(String[] args) { Map map = new HashMap<>(); //map.add(); map.put("itheima001","小智"); map.put("itheima002","小美"); map.put("itheima003","大胖"); System.out.println(map); }}
方法介绍
示例代码
package com.itheima.mapdemo1;import java.util.HashMap;import java.util.Map;/** * Map的基本方法 */public class MyMap2 { public static void main(String[] args) { Map map = new HashMap<>(); map.put("itheima001","小智"); map.put("itheima002","小美"); map.put("itheima003","大胖"); map.put("itheima004","小黑"); map.put("itheima005","大师"); //method1(map); //method2(map); //method3(map); //method4(map); //method5(map); //method6(map); //method7(map); } private static void method7(Map map) { // int size() 集合的长度,也就是集合中键值对的个数 int size = map.size(); System.out.println(size); } private static void method6(Map map) { // boolean isEmpty() 判断集合是否为空 boolean empty1 = map.isEmpty(); System.out.println(empty1);//false map.clear(); boolean empty2 = map.isEmpty(); System.out.println(empty2);//true } private static void method5(Map map) { // boolean containsValue(Object value) 判断集合是否包含指定的值 boolean result1 = map.containsValue("aaa"); boolean result2 = map.containsValue("小智"); System.out.println(result1); System.out.println(result2); } private static void method4(Map map) { // boolean containsKey(Object key) 判断集合是否包含指定的键 boolean result1 = map.containsKey("itheima001"); boolean result2 = map.containsKey("itheima006"); System.out.println(result1); System.out.println(result2); } private static void method3(Map map) { // void clear() 移除所有的键值对元素 map.clear(); System.out.println(map); } private static void method2(Map map) { // V remove(Object key) 根据键删除键值对元素 String s = map.remove("itheima001"); System.out.println(s); System.out.println(map); } private static void method1(Map map) { // V put(K key,V value) 添加元素 //如果要添加的键不存在,那么会把键值对都添加到集合中 //如果要添加的键是存在的,那么会覆盖原先的值,把原先值当做返回值进行返回。 String s = map.put("itheima001", "aaa"); System.out.println(s); System.out.println(map); }}
方法介绍
示例代码
package com.itheima.mapdemo1;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * Map的第一种遍历方式 */public class MyMap3 { public static void main(String[] args) { //创建集合并添加元素 Map map = new HashMap<>(); map.put("1号丈夫","1号妻子"); map.put("2号丈夫","2号妻子"); map.put("3号丈夫","3号妻子"); map.put("4号丈夫","4号妻子"); map.put("5号丈夫","5号妻子"); //获取到所有的键 Set keys = map.keySet(); //遍历Set集合得到每一个键 for (String key : keys) { //通过每一个键key,来获取到对应的值 String value = map.get(key); System.out.println(key + "---" + value); } }}
方法介绍
示例代码
package com.itheima.mapdemo1;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * Map的第二种遍历方式 */public class MyMap4 { public static void main(String[] args) { //创建集合并添加元素 Map map = new HashMap<>(); map.put("1号丈夫","1号妻子"); map.put("2号丈夫","2号妻子"); map.put("3号丈夫","3号妻子"); map.put("4号丈夫","4号妻子"); map.put("5号丈夫","5号妻子"); //首先要获取到所有的键值对对象。 //Set集合中装的是键值对对象(Entry对象) //而Entry里面装的是键和值 Set> entries = map.entrySet(); for (Map.Entry entry : entries) { //得到每一个键值对对象 String key = entry.getKey(); String value = entry.getValue(); System.out.println(key + "---" + value); } }}
1.HashMap小结
(共4点,第4点是对forEache的解析)
1.案例需求
2.实现思路
3.代码实现
学生类
package com.itheima.mapdemo1;public class Student{ private String name; private int age; public Student() { } public Student(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; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; }}
测试类
package com.itheima.mapdemo1;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * Map的练习 */public class MyMap5 { public static void main(String[] args) { HashMap hm = new HashMap<>(); Student s1 = new Student("xiaohei",23); Student s2 = new Student("dapang",22); Student s3 = new Student("xiaomei",22); hm.put(s1,"江苏"); hm.put(s2,"北京"); hm.put(s3,"天津"); //第一种:先获取到所有的键,再通过每一个键来找对应的值 Set keys = hm.keySet(); for (Student key : keys) { String value = hm.get(key); System.out.println(key + "----" + value); } System.out.println("==================================="); //第二种:先获取到所有的键值对对象。再获取到里面的每一个键和每一个值 Set> entries = hm.entrySet(); for (Map.Entry entry : entries) { Student key = entry.getKey(); String value = entry.getValue(); System.out.println(key + "----" + value); } System.out.println("==================================="); //第三种: hm.forEach( (Student key, String value)->{ System.out.println(key + "----" + value); } ); }}
4.forEach方法解析
1.TreeMap-小结
1.创建学生类
2.创建TreeMap集合对象
3.创建学生对象
4.添加学生对象
5.遍历输出
学生类
package com.itheima.maptest;public class Student/* implements Comparable*/{ private String name; private int age; public Student() { } public Student(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; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; } /* @Override public int compareTo(Student o) { //按照年龄进行排序 int result = o.getAge() - this.getAge(); //次要条件,按照姓名排序。 result = result == 0 ? o.getName().compareTo(this.getName()) : result; return result; }*/}
测试类
package com.itheima.maptest;import java.util.Comparator;import java.util.TreeMap;/** * 需求:创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String)。 * 学生属性姓名和年龄,按照年龄进行排序并遍历。 */public class Test1 { public static void main(String[] args) { TreeMap tm = new TreeMap<>(new Comparator() { @Override public int compare(Student o1, Student o2) { int result = o1.getAge() - o2.getAge(); result = result== 0 ? o1.getName().compareTo(o2.getName()) : result; return result; } }); Student s1 = new Student("xiaohei",23); Student s2 = new Student("dapang",22); Student s3 = new Student("xiaomei",22); tm.put(s1,"江苏"); tm.put(s2,"北京"); tm.put(s3,"天津"); tm.forEach( (Student key, String value)->{ System.out.println(key + "---" + value); } ); }}