JavaSE

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;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读