2、Comparable与Comparator的使用

2019-12-12  本文已影响0人  lois想当大佬

一、概述
  Comparable与Comparator都可以实现排序的功能。如何选择?
可以考虑2点:
  1、Comparable是内比较器,需要类实现接口,重写compareTo方法,由于业务代码耦合了比较器代码,不利于后期修改,因此适合类设计之初有排序需求时使用。
  2、Comparator是外比较器,业务代码无须耦合比较器代码,因此适合后期有排序需求时再进行扩展。
  在Collections工具类中有一个排序方法sort,此方法可以只传一个集合,默认使用的比较器就是Comparable中的compareTo方法。
  在Collections工具类中有一个排序方法sort, 传入集合和比较器,使用的便是Comparator的compare方法

一、Comparable使用示例
1、UserComparable.java

package com.hello.test.compare;

/**
 * 定义User类的时候如果有排序的需求,可以实现Comparable接口。
 * 缺点:业务代码耦合了比较器,不利于后期功能修改
 */
public class UserComparable implements Comparable<UserComparable> {
    private String name;
    private int age;

    public UserComparable() {
    }
    public UserComparable(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

    /**
     * this和o进行比较,若返回值大于0则this大于o,
     * 返回值等于0则是this等于o,返回值小于0则是this<o
     * @param o
     * @return
     */
    @Override
    public int compareTo(UserComparable o) {
        // java的很多类已经实现了Comparable接口,比如说String,Integer等类
        if (this.name.compareTo(o.name)==0){
            if (this.age == o.age){
                return 0;
            }else if (this.age >o.age){
                return 1;
            }else {
                return -1;
            }
        }else if (this.name.compareTo(o.name)>0){
            return 1;
        }else {
            return -1;
        }
    }
}

2、TestComparable.java

package com.hello.test.compare;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestComparable {
    /**
     * 在Collections工具类中有一个排序方法sort,此方法可以只传一个集合,
     * 默认使用的比较器就是Comparable中的compareTo方法
     * @param args
     */
    public static void main(String[] args) {
        List<UserComparable> list = new ArrayList<>();
        list.add(new UserComparable("aaa", 23));
        list.add(new UserComparable("aaa", 12));
        list.add(new UserComparable("bbb", 12));
        list.add(new UserComparable("ccc", 45));
        Collections.sort(list);
        for (UserComparable user: list) {
            System.out.println(user.toString());
        }
    }
}
        // 结果:
        //UserComparable{name='aaa', age=12}
        //UserComparable{name='aaa', age=23}
        //UserComparable{name='bbb', age=12}
        //UserComparable{name='ccc', age=45}

二、Comparator使用示例
1、User.java

package com.hello.test.compare;

public class User {
    private String name;
    private Integer age;

    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

2、UserComparator.java

package com.hello.test.compare;

import java.util.Comparator;

/**
 * 外比较器
 * 优点:业务代码User解耦合,后期扩展不需要修改业务代码,直接增加比较器Comparator即可
 */
public class UserComparator implements Comparator<User> {

    /**
     * 返回值大于0则o1大于o2,返回值等于0则o1等于o2,返回值小于0则o1小于o2
     * @param o1
     * @param o2
     * @return
     */
    @Override
    public int compare(User o1, User o2) {
       if (o1.getName().compareTo(o2.getName()) == 0) {
            if (o1.getAge() == o2.getAge()) {
                return 0;
            } else if (o1.getAge() > o2.getAge()) {
                return 1;
            } else {
                return -1;
            }
       } else if (o1.getName().compareTo(o2.getName()) > 0) {
           return 1;
       } else {
           return -1;
       }
    }
}

3、TestComparator.java

package com.hello.test.compare;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestComparator {

    /**
     * 在Collections工具类中有一个排序方法sort, 传入集合和比较器
     * 使用的便是Comparator的compare方法
     * @param args
     */
    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        list.add(new User("aaa", 23));
        list.add(new User("ccc", 45));
        list.add(new User("aaa", 12));
        list.add(new User("bbb", 12));
        System.out.println("排序前:");
        for (User user: list) {
            System.out.println(user.toString());
        }

        Collections.sort(list, new UserComparator());

        System.out.println("排序后:");
        for (User user: list) {
            System.out.println(user.toString());
        }
    }
}
        // 排序前:
        //UserComparator{name='aaa', age=23}
        //UserComparator{name='ccc', age=45}
        //UserComparator{name='aaa', age=12}
        //UserComparator{name='bbb', age=12}
        //排序后:
        //UserComparator{name='aaa', age=12}
        //UserComparator{name='aaa', age=23}
        //UserComparator{name='bbb', age=12}
        //UserComparator{name='ccc', age=45}
上一篇 下一篇

猜你喜欢

热点阅读