一.TreeSet类
1.TreeSet类,树集,线程不安全,可以对Set集合中的元素进行排序
如何保证元素唯一,排序时如何进行的呢?树形结构:
2.TreeSet排序的原理
- 元素本身具有比较性(自然排序)Comparable -> compareTo
- 集合具有比较性(比较器排序)Comparator -> compare
实现Comparable接口的方式成为自然排序!
*TreeSet练习
- 存储字符并遍历
- 存储自定义类对象并遍历,两种方式实现(元素具有比较性,集合具有比较性)
- 从键盘上录入3个学生的信息,包括语文、数学、英语的成绩三个成员变量,并根据总成绩进行排序。
三.Map集合
1.Map与Collection不同(单列,双列)
- Map与Collection在集合框架中并列存在
- Map存储的时键值对<K,V>
- Map存储元素使用put方法,Collection使用add方法
- Map集合没有直接取出元素的方法,而是先转成Set集合,再通过迭代获取元素
- Map集合键要保证唯一性
2.Map集合中常用类
- Hashtable:线程安全,速度慢,不允许存放null值,null键,已被HashMap替代。
- HashMap:线程不安全,速度快,允许存放null值,null键
- TreeMap:对键进行排序,排序原理与TreeSet相同。
- Map中的算法要求都是针对Key,和Value无关。
3.HashMap功能
- V put(Key k,v value)
- V get(Object key)
- V remove(Object key)
- void clear( )
- boolean isEmpty( )
- int size( )
特殊功能:
- Set<K> keySet( )
- Collection<V> values( )
4.HashMap遍历方式
- 先获取键的集合,再通过键找值:Object get(Object key)
- 先获取键值对的集合,再找其中的键和值
- Set<Entry<K,V>>entrySet( )
- getKey( )
- getValue( )
5.HashMap练习
- HashMap<String,String>
- HashMap<Integer,String>
- HashMap<String,Student>
- HashMap<Student,String>
6.LinkedHashMap
是HashMap的链表实现,由哈希表保证了键的唯一性,由链表保证了元素的存取顺序
7.TreeMap
基于树的Map,它的键唯一,并可以自动排序
根据使用的构造方法决定是使用元素本身可比性,还是使用集合的可比性
样例:TreeMap<String,String>
TreeMap<Student,String>
练习:
8.集合嵌套
- HashMap嵌套HashMap
- HashMap嵌套ArrayList
- ArrayList嵌套HashMap
9.总框架图
10.集合框架中的工具类
Collections:
- 对集合进行查找
- 取出结合中的最大值,最小值
- 对List集合进行排序
Arrays
- 将数组转成List集合
- 对数组进行排序
- 对数组进行二分查找
练习1.树形结构TreeSet原理,实现元素排序的方法之一,自然排序
package com.test2; import java.util.TreeSet; /* * TreeSet: * 底层使用的是二叉树保存数据! * * TreeSet去重且排序的第一种方式: * 让元素具有比较性:让元素所在的类实现Comparable接口.实现其中的compareTo()方法,通过方法的返回值决定当前元素到底是否能添加. * 放左还是放右! * * * */ class Student implements Comparable<Student>{//接口 private String name; private int 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; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { super(); // TODO Auto-generated constructor stub } /** * 通过该方法的返回值判断要添加的元素存放的位置: * 正数:放到参数节点的右侧 * 负数:放到参数节点的左侧 * 0:当前元素不能添加! */ @Override public int compareTo(Student o) { //首要条件:判断年龄 // return this.getAge() - o.getAge(); //当年龄相同时,判断名字:字符已经实现了Comparable接口,可以直接调用它的compareTo方法 int r1 = -(this.getAge() - o.getAge()); int r2 = r1 == 0? this.getName().compareTo(o.getName()):r1; return r2; } } public class TreeSetDemo { public static void main(String[] args) { /* //使用TreeSet存储基本数据类型对象! TreeSet<Integer> set = new TreeSet<>(); set.add(10); set.add(10); set.add(1); set.add(100); set.add(50); set.add(6); set.add(2); for (Integer i : set) { System.out.println(i); } */ //存储自定义对象 TreeSet<Student> set = new TreeSet<>(); // Student s1 = new Student("zoms", 10); Student s2 = new Student("zom", 100); set.add(s1); set.add(s2); for (Student s : set) { System.out.println(s.getName() +","+ s.getAge()); } } }
思考:自然排序和比较器排序同时存在时,哪个起作用?
3.存储自定义类对象并遍历
package com.test3; /* * 存储自定义类对象并遍历 * */ import java.util.Comparator; import java.util.TreeSet; class Student /* implements Comparable<Student> */ { private String name; private int 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; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { super(); // TODO Auto-generated constructor stub } /* * @Override public int compareTo(Student o) { //先比名字 int r1 = * this.getName().compareTo(o.getName()); //如果名字相同,再比年龄 int r2 = r1 == * 0?this.getAge() - o.getAge():r1; return r2; } */ } public class Demo { public static void main(String[] args) { /* * //自然排序 TreeSet<Student> set = new TreeSet<Student>(); //创建元素添加到集合 * Student s1 = new Student("abc", 10); Student s2 = new Student("abc", * 10); * * set.add(s1); set.add(s2); for (Student s : set) { * System.out.println(s.getName()+","+s.getAge()); } */ // 比较器排序 TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // 先比名字 int r1 = o1.getName().compareTo(o2.getName()); // 如果名字相同,再比年龄 int r2 = r1 == 0 ? o1.getAge() - o2.getAge() : r1; return r2; } }); // 创建元素添加到集合 Student s1 = new Student("abc", 10); Student s2 = new Student("abc", 1); set.add(s1); set.add(s2); for (Student s : set) { System.out.println(s.getName()+","+s.getAge()); } } }
4.从键盘上录入3个学生的信息,包括语文,数学,英语的成绩三个成员变量,并根据总成绩进行
package com.test3; import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; /* * .从键盘上录入3个学生的信息,包括语文,数学,英语的成绩三个成员变量,并根据总成绩进行排序 */ class Person{ private String name; private int ch; private int ma; private int en; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCh() { return ch; } public void setCh(int ch) { this.ch = ch; } public int getMa() { return ma; } public void setMa(int ma) { this.ma = ma; } public int getEn() { return en; } public void setEn(int en) { this.en = en; } public Person(String name, int ch, int ma, int en) { super(); this.name = name; this.ch = ch; this.ma = ma; this.en = en; } public Person() { super(); // TODO Auto-generated constructor stub } //定义方法:获取总成绩 public int getSum(){ return ch + ma + en; } } public class Demo2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //创建集合 TreeSet<Person> set = new TreeSet<>(new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { //先比总成绩: int r1 = -(p1.getSum() - p2.getSum()); //比语文 int r2 = r1 == 0?p1.getCh() - p2.getCh():r1; //比数学 int r3 = r2 == 0?p1.getMa() - p2.getMa():r2; //比名字 int r4 = r3 == 0?p1.getName().compareTo(p2.getName()):r3; return r4; } }); for(int i = 1;i<=3;i++){ System.out.println("输入第" + i + "个人的名字"); String name = sc.next(); System.out.println("输入第" + i + "个人的语文成绩:"); int ch = sc.nextInt(); System.out.println("输入第" + i + "个人的数学成绩:"); int ma = sc.nextInt(); System.out.println("输入第" + i + "个人的英文成绩:"); int en = sc.nextInt(); //封装成Person对象,并添加到集合中 set.add(new Person(name, ch, ma, en)); } // for (Person p : set) { System.out.println(p.getName() +","+ p.getCh() +","+ p.getMa() +","+ p.getEn()); } } }