TreeSet 的使用
- 无序能排序默认排序是升序
- 不可重复
- 如果使用泛型统一了数据类型可以排序,但是混和数据类型排序会发生异常(ClassCaseException) 类型转换异常(运行时异常)
- JDK 1.7 之后可以自动类型推断,<> 钻石表达式
构造函数
- 无参
TreeSet<> ts = new TreeSet<>();
- 有参
TreeSet<> ts = new TreeSet<>();
class 类名 implements Comparator <>
- 结论
- TreeSet 集合底层时TreeMap 的key元素组成的集合
// 底层
public TreeSet() {
this(new TreeMap<>());
}
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
- 凡是实现了Comparable接口的类都可以比较,要重写compareTo()方法
- 只有同类型或者继承的子类才能进行比较,因为底层进行了类型判断
Comparable<? super K> k = (Comparable<? super K>) key
使用TreeSet进行比较的方式
方式一:实现Comparable 接口
package java.lang class Goods implements Comparable <Goods>{}
缺点: 比较规则经常变化,不合适
方式二:实现Comparator接口
package java.util; public interface Comparator<T>; TreeSet <Goods> ts =new TreeSet<>(new comparaPrice());
方式三:规则比较单一,匿名内部类,方便一次性
TreeSet<Goods> ts = new TreeSet<>(new Comparator<Gods>(){ @Override public int compare(Goods o1, Goods o2) { return o1.sales - o2.sales; } })
TreeMap
- 特点:无序,存取的顺序不同
- 自动排序,默认升序
- TreeMap底层采用的二叉树数据结构
HashMap
- HashMap底层是哈希表
- [ 单向链表1,单向链表2,单向链表3…]
- 用HashMap存放自定义类型的元素,同时重写hashCode()和equals()
- 用HashSet存放自定义类型的元素,同时重写hashCode()和equals()
哈希表的数据结构
实例分析:
分别用Comparable和Comparator两个接口对下列四位同学的成绩做降序排序,如果成绩一样,
那在成绩排序的基础上按照年龄由小到大排序。
姓名(String) 年龄(int) 分数(float)
马超 20 90.0F
黄忠 22 90.0F
李典 20 89.0F
曹操 22 100F
代码:思路,这个题目写了三遍,第一遍可能是天气原因(随便找了 个理由甩一甩)~
第二遍,是通过面向接口编程,把所有的逻辑都写到了一个Person类中
第三遍,使用到了多态(父类型引用指向子类型对象),面向接口编程等之前学习过的知识,而不是把所有的逻辑一箩筐的扎堆处理,可能代码有点多!
//Person 类
package restructure_zuoYe;
import java.util.Objects;
public class Person {
private String name;
private int age;
private float grade; //成绩
public Person() {}
public Person(String name, int age, float grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", grade=" + grade +
'}';
}
@Override
public 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 &&
Float.compare(person.grade, grade) == 0 &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, grade);
}
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 float getGrade() {
return grade;
}
public void setGrade(float grade) {
this.grade = grade;
}
}
// Comparable_Person 类
package restructure_zuoYe;
public class Comparable_Person extends Person implements Comparable<Person>{
public Comparable_Person() {}
public Comparable_Person(String name, int age, float grade) {
super(name, age, grade);
}
@Override
public int compareTo(Person o) {
// 如果成绩相同就按照年龄升序进行排序
if(this.getGrade() == o.getGrade()) {
return this.getAge()-o.getAge();
}
else {
// 成绩不同,进行降序
float temp = this.getGrade()-o.getGrade();
if(temp>0) {
return -1;
}
else if (temp<0) {
return 1;
}
else{
return (int)temp;
}
}
}
}
// Comparator_Person 类
package restructure_zuoYe;
import java.util.Comparator;
public class Comparator_Person extends Person implements Comparator<Person> {
public Comparator_Person() {
}
public Comparator_Person(String name, int age, float grade) {
super(name, age, grade);
}
@Override
public int compare(Person o1, Person o2) {
if(o1.getGrade() == o2.getGrade()) {
return o1.getAge()-o2.getAge();
}
else {
// 成绩不同,进行降序
float temp = o1.getGrade()-o2.getGrade();
if(temp>0) {
return -1;
}
else if (temp<0) {
return 1;
}
else{
return (int)temp;
}
}
}
}
// Test 测试类: 可能是自己强行使用多态,new Person 的时候就多new了几个,不然只要new一组person就可以解决问题,就是这么喜欢折腾!
package restructure_zuoYe;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
Person person1 = new Comparable_Person("马超",20,90.0F);
Person person2 = new Comparable_Person("黄忠",22,88.0F);
Person person3 = new Comparable_Person("李典",19,90.0F);
Person person4 = new Comparable_Person("曹操",22,100.0F);
TreeSet<Person> ts = new TreeSet();
ts.add(person1);
ts.add(person2);
ts.add(person3);
ts.add(person4);
System.out.println("使用Comparable接口:");
Iterator<Person> iterator = ts.iterator();
while (iterator.hasNext()) {
Person next = iterator.next();
System.out.println(next);
}
Person p1 = new Comparator_Person("马超",20,90.0F);
Person p2 = new Comparator_Person("黄忠",22,88.0F);
Person p3 = new Comparator_Person("李典",19,90.0F);
Person p4 = new Comparator_Person("曹操",22,100.0F);
System.out.println("使用Comparator接口:");
Set<Person> ts1 = new TreeSet(new Comparator_Person()); // 面向接口编程
ts1.add(p1);
ts1.add(p2);
ts1.add(p3);
ts1.add(p4);
for (Person person :ts1) {
System.out.println(person);
}
}
}
- 例题总结:只要原因,还是在听老师上课的时候,似懂非懂,感觉自己听懂了,实际上没有弄东其原理与精髓,以至于这个题目从下午到晚上才开始有了那么一点感觉,深刻的感受到了上课认真听讲的重要性,其次是要深刻理解HashSet 与 TreeSet 之间的关系与区别,最后不懂的知识一定不要泄气,多敲敲代码,第一次学看看别人的代码也不算一件很不好意思的事情,毕竟不懂就是不懂,在知识面前,没有知识是显得那么无助与渺小!