- 一、二叉树的了解
- 二、使用比较器将数据存储到TreeSet中
- 三、匿名内部类
- 1.基于抽象类的匿名内部类
- 2.基于接口的匿名内部类
- 四、内部类
- 成员内部类
一、二叉树的了解
通过查阅API我们得知TreeSet集合是基于TreeMap的实现,而TreeMap是基于二叉树(红黑树)结构,也就是说TreeSet集合的底层使用的二叉树(红黑树)结构。
树结构:它也是数据结构中的一种。在计算机领域中树结构指的是倒立的树。
树结构存储的数据,每个数据也需要节点来保存。
而TreeSet集合底层是二叉树的数据结构,什么是二叉树呢?
二叉树:每个节点的下面最多只能有2个子节点。
说明:最多表示一个节点下面可以有两个子节点或者一个子节点或者没有子节点。
在二叉树的根节点左侧的节点称为左子树,在根节点的右侧的节点称为右子树。
既然已经得知TreeSet集合底层是二叉树,那么二叉树是怎样存储数据的呢?是怎样保证存储的数据唯一并有序的呢?
二叉树的存储流程:
当存储一个元素的时候,如果是树的第一个元素,这个元素就作为根节点。
如果不是第一个元素,那么就拿要存储的元素与根节点进行比较大小:
大于根元素:就将要存储的元素放到根节点的右侧,作为右叶子节点。
等于根元素:丢弃。
小于根元素:就将要存储的元素放到根节点的左侧,作为左叶子节点。
总结:二叉树是通过比较大小来保证元素唯一和排序的。
二、使用比较器将数据存储到TreeSet中如果想要使用比较器的写法,就必须在new TreeSet()的时候加上比较器对象。
TreeSet有一个有参构造,有参构造的方法是Comparator的对象。
Comparator是一个接口,不能实例化,需要再写一个类去实现这个接口。
代码如下(示例):
//Employee类
package com.qfedu.c_comparator;
public class Employee{
private String name;
private int age;
public Employee () {
}
public Employee(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;
}
public String toString() {
return "Employee{name = " + name + ", age = " + age + "}";
}
}
Comparator接口类 package com.qfedu.c_comparator; import java.util.Comparator; public class MyComparator implements Comparator{ @Override public int compare(Employee o1, Employee o2) { if (o1.getName().compareTo(o2.getName()) ==0){ return o1.getAge() - o2.getAge(); } return o1.getName().compareTo(o2.getName()); } }
测试类
package com.qfedu.c_comparator;
import java.util.Set;
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
Set emps = new TreeSet<>(new MyComparator());
Employee employee = new Employee("老邢",78);
Employee employee1 = new Employee("骚磊",68);
Employee employee2 = new Employee("博哥",28);
Employee employee3 = new Employee("博哥",23);
emps.add(employee);
emps.add(employee1);
emps.add(employee2);
emps.add(employee3);
System.out.println(emps);
}
}
三、匿名内部类
目的是为了减少代码量
1.基于抽象类的匿名内部类代码如下(示例):
Person抽象类
package com.qfedu.d_anno;
public abstract class Person {
public abstract void eat();
public abstract void call();
public void sleep() {
System.out.println("好想睡觉!!!");
}
}
2.基于接口的匿名内部类
代码如下(示例):
接口
package com.qfedu.e_anno;
public interface B {
void get();
}
package com.qfedu.e_anno;
public class Demo {
public static void main(String[] args) {
B b = new B() {
@Override
public void get() {
System.out.println("得锦旗!!");
}
};
b.get();
}
}
四、内部类
从字面意思来理解:在一个类的内部再创建一个类,这个新建的类就叫内部类
成员内部类成员内部类的创建步骤:
1.实例化外部类,类对象
2.实例化内部类对象,但是new得改为 外部对象.new
代码如下(示例):
MemberDemo类
package com.qfedu.f_inner;
public class MemberDemo {
String name = "张三";
int age = 20;
public void printf() {
System.out.println("打印着玩的!!!");
}
class Inner {
String name = "李四";
//在Inner类中可以访问外部类的属性和方法
public void test() {
printf();
System.out.println(age);
System.out.println(name);
//访问外部类对象的属性时,用 类名.this.属性
System.out.println(MemberDemo.this.name);
}
}
}
测试类
package com.qfedu.f_inner;
public class Demo {
public static void main(String[] args) {
//成员内部类的创建步骤
//1.实例化外部类 类对象
MemberDemo memberDemo = new MemberDemo();
//2.实例化内部类对象
MemberDemo.Inner inner = memberDemo.new Inner();
inner.test();
}
}



