java - 比较器记录所学

引言:在java中涉及到对象的排序,常常用到比较器,总不能使用> ,< 吧。而实现排序的方式有两种,自然排序和定制排序


一、自然排序:java.lang.Comparable

要求如下:

  1. 对于自定义类,继承Comparable接口并实现compareTo方法。
  2. 调用方法判断比较当前两个对象的大小,如果当前对象this大于形参对应对象obj的时候,则返回正整数;反之,返回负数;如果相同,就返回0。
  3. 使用Array.sort()分类或者使用Collections.sort()方法排序,不过这时候要创建list接口,如果只是对集合操作,就还是Array.sout()方法比较好。
public class Compare {
     
    public static void main(String[] args) {
     
        //方法一:Arrays.sort
        Person[] p = new Person[6];
        p[0] = new Person(18, "John", 8000);
        p[1] = new Person(18, "Tom", 7000);
        p[2] = new Person(18, "Jimi", 9000);
        p[3] = new Person(14, "Mary", 10000);
        p[4] = new Person(28, "MY", 4000);
        p[5] = new Person(22, "Wuyif", 5000);
        Arrays.sort(p);
        System.out.println(Arrays.toString(p));


        //方法二:创建list排序
        ArrayList<Person> people = new ArrayList<Person>();
        people.add(p[0]);
        people.add(p[1]);
        people.add(p[2]);
        people.add(p[3]);
        people.add(p[4]);
        people.add(p[5]);
        Collections.sort(people);
        System.out.println(people);
    }

}

class Person implements Comparable {
     
    private int age;
    private String name;
    private double salary;

    public Person(int age, String name, double salary) {
     
        this.age = age;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
     
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }

    @Override
    public int compareTo(Object o) {
     
        //判断是否属于Person类,当然使用泛型能够更加方便
        if (o instanceof Person) {
     
            //强转
            Person p = (Person) o;
            if (this.age > p.age) {
     
                return 1;
            } else if (this.age < p.age) {
     
                return -1;
            } else {
     
                //如果年龄一样,就按照薪水排序,如果从想高到低加一个负号就可以了
                return Double.compare(this.salary, p.salary);
            }
        }
        //不是Person类,抛出异常
        throw new RuntimeException("输入的形参不是Perso类,无法比较");
    }
}


二、定制排序:java.util.Comparator

  1. 我们在对对象进行排序的时候,有一些元素没有实现接口重写方法,或者当有一些实现接口之后重写的方法不是我们想要的排序时,就可以使用自定义排序
  2. 使用Comparator进行定制排序,重写compare(Object o1,Object o2)方法,o1 > o2,返回正数;o1 = o2,返回0;o1 < o2,返回负数。
  3. 使用Array.sort()分类或者使用Collections.sort()方法排序,使用Collections的方法同上自然排序
public class MyCompare {
     
    public static void main(String[] args) {
     
        //方法一:Arrays.sort
        Person1[] p1 = new Person1[6];
        p1[0] = new Person1(18, "John", 8000);
        p1[1] = new Person1(18, "Tom", 7000);
        p1[2] = new Person1(18, "Jimi", 9000);
        p1[3] = new Person1(14, "Mary", 10000);
        p1[4] = new Person1(28, "MY", 4000);
        p1[5] = new Person1(22, "Wuyif", 5000);
        Arrays.sort(p1, new Comparator<Person1>() {
     
            @Override
            public int compare(Person1 o1, Person1 o2) {
     
                //这里演示按名字排序
                return o1.getName().compareTo(o2.getName());
            }
        });
        System.out.println(Arrays.toString(p1));


        //方法二:创建list排序
        ArrayList<Person1> people = new ArrayList<Person1>();
        people.add(p1[0]);
        people.add(p1[1]);
        people.add(p1[2]);
        people.add(p1[3]);
        people.add(p1[4]);
        people.add(p1[5]);
        Collections.sort(people, new Comparator<Person1>() {
     
            @Override
            public int compare(Person1 o1, Person1 o2) {
     
                //这里只演示一种情况,年龄排序
                int compare = Integer.compare(o1.getAge(), o2.getAge());
                return compare;
            }
        });
        System.out.println(people);
    }
}

class Person1 {
     
    private int age;
    private String name;
    private double salary;

    public Person1 (int age, String name, double salary) {
     
        this.age = age;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
     
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public double getSalary() {
     
        return salary;
    }

    public void setSalary(double salary) {
     
        this.salary = salary;
    }
}



三、对Set排序

首先要注意:LinkHashSet和HashSet是不支持排序的,所以这里演示对TreeSet进行排序。值得注意的是: 在实现自然排序的时候,如果使用add加入的元素没有实现Comparable接口,程序就会抛出异常ClassCastException

//---------------1。自然排序--------------
public class TreeSetSort {
     
    public static void main(String[] args) {
     
        Set<Person2> set = new TreeSet<>();
        Person2 []p2 = new Person2[4];
        p2[0] = new Person2(18, "John", 8000);
        p2[1] = new Person2(18, "Tom", 7000);
        p2[2] = new Person2(14, "Mary", 10000);
        p2[3] = new Person2(22, "Wuyif", 5000);
        set.add(p2[0]);
        set.add(p2[1]);
        set.add(p2[2]);
        set.add(p2[3]);
        System.out.println(set);
    }
}

class Person2 implements Comparable {
     
    private int age;
    private String name;
    private double salary;

    public Person2(int age, String name, double salary) {
     
        this.age = age;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
     
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }

    @Override
    public int compareTo(Object o) {
     
        //判断是否属于Person类,当然使用泛型能够更加方便
        if (o instanceof Person2) {
     
            //强转
            Person2 p = (Person2) o;
            if (this.age > p.age) {
     
                return 1;
            } else if (this.age < p.age) {
     
                return -1;
            } else {
     
                //如果年龄一样,就按照薪水排序,如果从想高到低加一个负号就可以了
                return Double.compare(this.salary, p.salary);
            }
        }
        //不是Person2类,抛出异常
        throw new RuntimeException("输入的形参不是Person2类,无法比较");
    }
}


//--------------2.定制排序----------------

public class TreeSetSort1 {
     
    public static void main(String[] args) {
     
        //写法一:普通写法,繁杂
//        Set set1 = new TreeSet<>(new Comparator() {
     
//            @Override
//            public int compare(Person3 o1, Person3 o2) {
     
//                //演示按薪水排序
//                return Double.compare(o1.getSalary(), o2.getSalary());
//            }
//        });

        //写法二:Lambda表达式写法
        Set<Person3> set1 = new TreeSet<Person3>((o1, o2) -> {
     
           return  Double.compare(o1.getSalary(), o2.getSalary());
        });



        Person3 []p = new Person3[4];
        p[0] = new Person3(18, "John", 8000);
        p[1] = new Person3(18, "Tom", 7000);
        p[2] = new Person3(14, "Mary", 10000);
        p[3] = new Person3(22, "Wuyif", 5000);
        set1.add(p[0]);
        set1.add(p[1]);
        set1.add(p[2]);
        set1.add(p[3]);
        System.out.println(set1);
    }
}

class Person3 {
     
    private int age;
    private String name;
    private double salary;

    public Person3(int age, String name, double salary) {
     
        this.age = age;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
     
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public double getSalary() {
     
        return salary;
    }

    public void setSalary(double salary) {
     
        this.salary = salary;
    }
}



四、对Map排序(以HashMap为例)

HashMap本身是无序的集合且是散列表,要排序就要借助其他的接口比如List,可以把Map里面的Node[]抽出存放在ArrayList中进行排序输出即可
java - 比较器记录所学_第1张图片

public class MapSort {
     
    public static void main(String[] args) {
     
        Map<Integer, Person4> map = new HashMap<>();
        map.put(1, new Person4(18, "John", 8000));
        map.put(2, new Person4(18, "Tom", 7000));
        map.put(3, new Person4(14, "Mary", 10000));
        map.put(4, new Person4(22, "Wuyif", 5000));
        //取出Node[],放入list中
        List<Map.Entry<Integer, Person4>> entries = new ArrayList<>(map.entrySet());
        //开始自定义排序
        Collections.sort(entries, new Comparator<Map.Entry<Integer, Person4>>() {
     
            @Override
            public int compare(Map.Entry<Integer, Person4> o1, Map.Entry<Integer, Person4> o2) {
     
                //这里演示用value中的薪水进行排序
                return Double.compare(o1.getValue().getSalary(), o2.getValue().getSalary());
            }
        });
        //或者用Iterator迭代器来遍历
        Iterator iterator = entries.iterator();
        while(iterator.hasNext()){
     
            System.out.println(iterator.next());
        }
        //4=Person{age=22, name='Wuyif', salary=5000.0}
        //2=Person{age=18, name='Tom', salary=7000.0}
        //1=Person{age=18, name='John', salary=8000.0}
        //3=Person{age=14, name='Mary', salary=10000.0}

        //**************************************************
        //当然,也可以将list中的数据放回map中,看自己喜欢了
        //如果要放回去,就用LinkHashMap放,否则因为map的存放机制,是不会变的
        LinkedHashMap<Integer, Person4> map1 = new LinkedHashMap<>();
        for(int i = 0; i < entries.size(); i++){
     
            map1.put(entries.get(i).getKey(), entries.get(i).getValue());
        }
        System.out.println(map1);

    }
}

class Person4 {
     
    private int age;
    private String name;
    private double salary;

    public Person4(int age, String name, double salary) {
     
        this.age = age;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
     
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public double getSalary() {
     
        return salary;
    }

    public void setSalary(double salary) {
     
        this.salary = salary;
    }
}




如有错误,欢迎各路大佬指出

你可能感兴趣的:(java比较器的用法,笔记,java)