TreeSet集合-两种排序方式
2021-05-17 本文已影响0人
AIGame孑小白
Set
HashSet:
- 数据结构是哈希表,线程不同步。
- 保证元素唯一性的原理:就是判断hashCode值是否相同,如果相同,还会继续判断元素的equals是否为true
TreeSet
TreeSet数据结构:二叉树
TreeSet会对元素进行排序
TreeSet
TreeSet treeSet = new TreeSet();
for (int i = 0; i < 4; i++) {
treeSet.add(i);
}
for(Iterator iterator = treeSet.iterator();iterator.hasNext();){
System.out.println(iterator.next());
}
//输出:
0
1
2
3
TreeSet treeSet = new TreeSet();
treeSet.add("adfg");
treeSet.add("aaaa");
treeSet.add("accc");
treeSet.add("ccad");
treeSet.add("bvdg");
for(Iterator iterator = treeSet.iterator();iterator.hasNext();){
System.out.println(iterator.next());
}
//输出:
aaaa
accc
adfg
bvdg
ccad
TreeSet自定义排序
当装入自定义类的元素时:TreeSet会根据元素实现Comparable的comparableTo方法进行默认排序,默认排序被称之为:自然排序
import java.util.TreeSet;
class Student{
private String name;
private int age;
public Student(String stuName,int stuAge){
this.name = stuName;
this.age = stuAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(new Student("张三",15));
treeSet.add(new Student("李四",16));
}
}
上面的代码,在第二次add元素的时候会报错cannot be cast to java.lang.Comparable,因为TreeSet会对元素进行排序,然而Student对象不具有可比性,因此:需要自定义排序
import java.util.Iterator;
import java.util.TreeSet;
class Student implements Comparable {
private String name;
private int age;
public Student(String stuName,int stuAge){
this.name = stuName;
this.age = stuAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Object o) {
if(!(o instanceof Student)){
throw new RuntimeException("该对象不属于Student");
}else{
if(this.age>((Student) o).getAge()){
return 1;
}else if(this.age<((Student) o).getAge()){
return -1;
}else {
//年龄相同判定为相同对象,则TreeSet不会存入该对象
return 0;
}
}
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(new Student("张三",15));
treeSet.add(new Student("李四",16));
treeSet.add(new Student("王五",36));
treeSet.add(new Student("赵六",1));
/**
* 会报错cannot be cast to java.lang.Comparable
* 因为TreeSet会对元素进行排序,然而Student对象不具有可比性
* 因此:需要自定义排序
* */
for (Iterator iterator = treeSet.iterator();iterator.hasNext(); System.out.println(((Student)iterator.next()).getName()));
}
}
因为上面的判断方法是更具sutdent.age判断排序的,所以,当年龄相同时compareTo返回0,TreeSet就不把该元素存入;其实String类也实现了Comparable接口,所以可以通过调用String的compareTo方法获取按照字典排序的方法得到返回值。
//年龄相同判定为相同对象,则TreeSet不会存入该对象
return this.name.compareTo(((Student)o).getName());
TreeSet第二种排序
就是让集合自身具备排序方式,把Comparator对象做为构造参数传入
class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
if (s1.getAge()>s2.getAge()){
return 1;
}
return 0;
}
}
//使用:
TreeSet treeSet = new TreeSet(new MyComparator());
其实Integer自己封装了compareTo方法,所以可以这样直接使用
class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
return new Integer(((Student)o1).getAge()).compareTo(new Integer(((Student)o2).getAge()));
}
}
但是!当主要条件判断完毕后,一定要判断次要条件,否则会丢失元素
class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
int num = new Integer(((Student)o1).getAge()).compareTo(new Integer(((Student)o2).getAge()));
if(num==0){
num = new Integer(((Student)o1).getName().length()).compareTo(new Integer(((Student)o2).getName().length()));
}
return num;
}
}