Java之Comparator使用举例

简介

Comparator是一个比较器接口,位于java.util包下,用于排序和比较。

代码举例

import java.util.*;

/**
 * @author :gongxr
 * @description:Comparator比较器
 */
@Slf4j
public class ComparatorDemo {
    public List<User> getList() {
        List<User> users = new ArrayList<>();
        User user = new User("Tom", 22, "Street #1");
        users.add(user);
        users.add(new User("Michael", 33, "Street #2"));
        users.add(new User("Lily", 25, "Street #3"));
        return users;
    }

    @Test
    public void testComparator() {
        List<User> users = getList();

        /*查询年龄最大的人*/
        Optional<User> max = users.stream().max(Comparator.comparing(User::getAge));
        log.info("maxAge: " + max.get().toString());

        /*名字最长的人*/
        Optional<String> max2 = users.stream().map(u -> u.getName()).max(Comparator.comparing(String::length));
        log.info("maxStringLength: " + max2.get());
    }


    /**
     * 排序
     * 在List或数组中的对象如果没有实现Comparable接口时,那么就需要调用者为需要排序的数组或List设置一个Compartor,
     * Compartor的compare方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序
     */
    class Dog {
        public int age;
        public String name;

        public Dog(int age, String name) {
            super();
            this.age = age;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Dog [age=" + age + ", name=" + name + "]";
        }
    }

    @Test
    public void test1() {
        List<Dog> list = new ArrayList<>();
        list.add(new Dog(5, "DogA"));
        list.add(new Dog(6, "DogB"));
        list.add(new Dog(7, "DogC"));
        Collections.sort(list, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o2.age - o1.age;
            }
        });
        System.out.println("给狗狗按照年龄倒序:" + list);

        Collections.sort(list, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o1.name.compareTo(o2.name);
            }
        });
        System.out.println("给狗狗按名字字母顺序排序:" + list);
    }


    /**
     * 分组
     * 使用Comparator和for循环处理列表,来进行分类;通过调用者实现Comparator接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。
     * 下面例子中分别按照狗狗的颜色和体重级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。
     * 下面抽了一个工具方法:dividerList,第一个参数为需要处理的数据源,第二参数是分组时的比较逻辑。
     */
    class Apple {
        public String color;
        public int weight;

        public Apple(String color, int weight) {
            super();
            this.color = color;
            this.weight = weight;
        }

        @Override
        public String toString() {
            return "Apple [color=" + color + ", weight=" + weight + "]";
        }
    }

    /*按条件分组*/
    public static <T> List<List<T>> divider(Collection<T> datas, Comparator<? super T> c) {
        List<List<T>> result = new ArrayList<List<T>>();
        for (T t : datas) {
            boolean isSameGroup = false;
            for (int j = 0; j < result.size(); j++) {
                if (c.compare(t, result.get(j).get(0)) == 0) {
                    isSameGroup = true;
                    result.get(j).add(t);
                    break;
                }
            }
            if (!isSameGroup) {
                // 创建
                List<T> innerList = new ArrayList<T>();
                result.add(innerList);
                innerList.add(t);
            }
        }
        return result;
    }

    @Test
    public void test2() {
        List<Apple> list = new ArrayList<>();
        list.add(new Apple("红", 205));
        list.add(new Apple("红", 131));
        list.add(new Apple("绿", 248));
        list.add(new Apple("绿", 153));
        list.add(new Apple("红", 332));
        list.add(new Apple("黄", 119));
        list.add(new Apple("黄", 224));
        List<List<Apple>> byColors = divider(list, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                // 按颜色分组
                return o1.color.compareTo(o2.color);
            }
        });
        System.out.println("按颜色分组" + byColors);

        List<List<Apple>> byWeight = divider(list, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                // 按重量级

                return (o1.weight / 100 == o2.weight / 100) ? 0 : 1;
            }
        });
        System.out.println("按重量级分组" + byWeight);
    }

}

 

posted @ 2021-03-10 15:37  星瑞  阅读(689)  评论(0编辑  收藏  举报