是SET接口的实现类
特点:唯一,无序
底层原理:哈希表
HashSets = new HashSet<>(); System.out.println(s.add(12)); //true s.add(5); s.add(33); System.out.println(s.add(12)); //false s.add(166); System.out.println(s.size()); //4 System.out.println(s); //[33, 5, 166, 12]
第一个数据可以添加成功,再次添加重复数据则添加失败。
hashset在数组中存放的位置通过hashcode和表达式计算得出。每将要放入一个元素都需要跟这个位置里的元素比较一下是否相等,所以数据的存放跟equals方法也有关。
同理得出,hashset表放入集合需要满足两个条件,有hashcode和equals方法(重写)
数组+链表=哈希表
LinkedHashset实现类特点:有序,唯一,按照输入顺序排列进行输出
(相当于在哈希表的基础上使用链表,把输入的每一个元素链接起来)
public class Test01 {
public static void main(String[] args) {
LinkedHashSet l = new LinkedHashSet<>();
l.add(2);
l.add(56);
l.add(43);
l.add(8);
l.add(3);
l.add(8);
System.out.println(l); //[2, 56, 43, 8, 3] 重复的8没被存进去
}
}
TreeSet
特点:唯一,无序且有序(没有按照输入顺序排列,而是按照升序进行排列)
public class Test01 {
public static void main(String[] args) {
TreeSet l = new TreeSet<>();
l.add(2);
l.add(56);
l.add(43);
l.add(8);
l.add(3);
l.add(8);
System.out.println(l); //[2, 3, 8, 43, 56]
}
}
原理:TreeSet底层是二叉树(逻辑结构),不断地拿数据跟第一个数据进行比较,如果比他大放在右边,比他小,放在左边,以此类推。中序遍历使TreeSet可以做到升序排列
这个过程中最重要的就是比较。所以放进来的数据的数据类型都实现了内部比较器
默认用内部比较器比较。想使用外部比较器比较需要实例化外部比较器,并作为参数传入TreeSet的构造器里(相当于指定外部比较器)
public class Test01 {
public static void main(String[] args) {
Comparator com = new bijiao01();
TreeSet l = new TreeSet<>(com);//指定外部比较器
l.add(new Student(18,"alili"));
l.add(new Student(9,"dlili"));
l.add(new Student(33,"blili"));
l.add(new Student(25,"flili"));
l.add(new Student(18,"mlili"));
//[Student{age=9, name='dlili'}, Student{age=18, name='alili'},
// Student{age=25, name='flili'}, Student{age=33, name='blili'}]
System.out.println(l);
}
}
比较器设置规则是按年龄比较,所以可以看到虽然姓名不同,但年龄相同也没被加入到集合当中。
比较器 内部比较器位置:类中,方法外
引用数据类型都有compareto方法
自定义类型想要使用compareto比较器需要先实现Comparable泛型接口(定义泛型为自制类),然后重写compareto方法
public class Student implements **Comparable外部比较器**{ private int age; private String name; @Override public int compareTo(Student o) { // //以年龄比较 // return this.age-o.age;//-4 //以姓名比较 return this.name.compareTo(o.name);//此时调的是String里的compareto方法 } }
自制类外新建一个类
创建外部比较器类需要实现Comparator接口重写compare方法
使用需要先获得外部比较器对象
好处是可以利用多态实现更多功能比较,拓展性好,
public class Student{
private int age;
private String name;
}
class bijiao01 implements Comparator {
@Override
public int compare(Student o1, Student o2) {
//比较年龄
return o1.getAge()-o2.getAge();
}
}
class bijiao03 implements Comparator {
//年龄不同比较年龄,年龄相同比较姓名
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge()==o2.getAge())
return o1.getName().compareTo(o2.getName());
else
return o1.getAge() - o2.getAge();
}
}
外部比较器优于内部比较器,提高了代码的拓展性



