guava之Ordering的使用实例

版权声明:觉得此文有用的,不嫌麻烦的,就留个言呐,或者点个赞呐(额,就是文章底部的“顶”啦),要是嫌弃麻烦呢,也麻烦点个赞嘛,要是实在不想点赞呢,也不是不可以。 但是,你要是想踩一脚呢,那还是赶紧,马上,快快的闪人。 小心我手里三十米长的大刀。 哼哼。想想都怕 !!! https://blog.csdn.net/qq_27093465/article/details/82224203

guava的ordering这个类的使用,帮助代码排序。很不错的。

1,先是简单的排序使用。

    /**
     * 默认的排序器
     * natural() 对可排序类型做自然排序,如数字按大小,日期按先后排序
     * reverse() 对当前的比较器进行反转
     * 自然排序,不能将汉字按首字母的顺序排序。
     */
    private static void naturalTest() {
        List<String> list = Lists.newArrayList("12", "2", "3", "33", "4", "44", "5", "55", "测试", "基线", "有钱");

        Ordering<Comparable> natural = Ordering.natural();
        list.sort(natural);
        System.out.println(list.toString());
        //反转
        list.sort(natural.reverse());
        System.out.println(list.toString());

        List<Integer> ints = Lists.newArrayList(12, 2, 3, 33, 4, 44, 5, 55);
        ints.sort(natural);
        System.out.println(ints.toString());
        ints.sort(natural.reverse());
        System.out.println(ints.toString());
    }

运行结果:

大师兄

对所传list进行系统默认的排序,一般情况下,没问题,但是如果要汉字内容按字母表顺序排的话就不行啦,

上面代码里面顺便示范了下“反转”,就是把排序器给反转一下的功能。对应的方法reverse();

2,常用的简单示范

    /**
     * 实现自定义的排序器
     * 常用姿势,传入需要比较的对象,然后使用对应的属性去compare,返回int。返回个比较器,然后list就可以使用啦。
     * 这地方使用的是简单的字符串,还示范了使用传入自定义类对象,根据某个属性排序的例子。
     */
    private static void usually() {
        List<String> list = Lists.newArrayList("12345", "2345", "345", "34", "4", "", "5", "55", "测试", "基线", "有钱");
        Ordering<String> lengthOrdering = new Ordering<String>() {
            @Override
            public int compare(String left, String right) {
                return Ints.compare(left.length(), right.length());
            }
        };
        list.sort(lengthOrdering);
        System.out.println(list.toString());

        list.sort(lengthOrdering.reverse());
        System.out.println(list.toString());


        //这样汉字就可以按首字母排序啦。
        Ordering<String> stringOrdering = new Ordering<String>() {
            @Override
            public int compare(String left, String right) {
                return Collator.getInstance(Locale.CHINA).compare(left, right);
            }
        };
        list.sort(stringOrdering);
        System.out.println(list.toString());
    }

运行结果:

大师兄

这个地方就对汉字的排序做了下操作,然后就可以按首字母排序啦。这地方使用的是简单的字符串来排序的。

3,对自定义的类,安照某个属性去排序的示范。

    /**
     * 对某个类的某个属性进行排序,很常用的姿势。
     */
    private static void classCompare() {
        //集合初始化的时候,若大小可知,应初始化固定大小的集合,也是个好习惯。
        List<Person> persons = Lists.newArrayListWithExpectedSize(4);
        persons.add(new Person(11, "周星驰"));
        persons.add(new Person(99, "陈世美"));
        persons.add(new Person(21, "潘金莲"));
        persons.add(new Person(15, "阿姆斯特丹"));

        persons.forEach(person -> System.out.print(person.getAge() + " "));
        System.out.println();
        persons.sort(OrderingConstants.AGE_ORDERING);
        persons.forEach(person -> System.out.print(person.getAge() + " "));
        System.out.println();

        persons.forEach(person -> System.out.print(person.getName() + " "));
        System.out.println();
        persons.sort(OrderingConstants.NAME_ORDERING);
        persons.forEach(person -> System.out.print(person.getName() + " "));
        System.out.println();
    }

运行结果:

大师兄

一个是按照年纪排序,一个是按照名字排序。额,这个person类,我就不展示啦,就一个名字String和年龄int两个属性。

还有,两个排序器,因为通用,我就给提出来了,放到一个单独的地方,可以通用。


    /**
     * 排序器的存储地方
     */
    interface OrderingConstants {

        /**
         * 按 age 排序,一定要判断一下对比的对象以及字段为null的情况,不然会bug的,虽然你当时可能不会报错。
         */
        Ordering<Person> AGE_ORDERING = new Ordering<Person>() {
            @Override
            public int compare(Person left, Person right) {
                if (left == null && right == null) {
                    return 0;
                }
                if (left == null) {
                    return 1;
                }
                if (right == null) {
                    return -1;
                }
                //这个地方不要自己去 a - b ,不要自己去算,因为int类型可以自己减少,但是long型可能就炸啦
                //这地方除了Ints,还有Longs,可以看下源码的这个文件夹下的相同效果的类。
                return Ints.compare(left.getAge(), right.getAge());
            }
        };

        /**
         * 按 name 排序,一定要判断一下对比的对象以及字段为null的情况,不然会bug的,虽然你当时可能不会报错。
         */
        Ordering<Person> NAME_ORDERING = new Ordering<Person>() {
            @Override
            public int compare(Person left, Person right) {
                if (left == null && right == null) {
                    return 0;
                }
                if (left == null) {
                    return 1;
                }
                if (right == null) {
                    return -1;
                }
                if (left.getName() == null && right.getName() == null) {
                    return 0;
                }
                if (left.getName() == null) {
                    return 1;
                }
                if (right.getName() == null) {
                    return -1;
                }
                return Collator.getInstance(Locale.CHINA).compare(left.getName(), right.getName());
            }
        };
    }

在实际项目里面,也可以这么干,把所有排序相关的排序器都放在一个地方,方便通用。

4,获得给定集合的有序副本。

    /**
     * 返回指定的元素的排序副本,不修改原来的list。
     */
    private static void sortedCopy() {
        List<String> list = Lists.newArrayList("12345", "2345", "345", "34", "4", "", "5", "55", "测试", "基线", "有钱");
        List<String> sortedCopy = Ordering.natural().sortedCopy(list);
        System.out.println(list.toString());
        System.out.println(sortedCopy.toString());
    }

大师兄

这个运行结果,可以看出来,原来的集合是啥还是啥,然后获得了个有序的集合。

5,把原来的顺序打乱,返回。

    /**
     * 把原来的顺序,任意打乱,返回。测试几次,返回的都一样,不是随机的。
     * 好像没啥用的样子
     */
    private static void arbitrary() {
        List<String> list = Lists.newArrayList("1", "2", "3", "4", "5", "4", "3", "2", "1", "0");
        Ordering<Object> arbitrary = Ordering.arbitrary();
        System.out.println(list.toString());
        list.sort(arbitrary);
        System.out.println(list.toString());
    }

大师兄

这个返回结果不是说每次都不一样,结果是固定都。

6,先是按照属性1排序,要是相同了,再继续按属性2排序。

    /**
     * 先是按年纪排序,年纪相同,再按名称排序。
     */
    private static void sortTwoWay() {
        //集合初始化的时候,若大小可知,应初始化固定大小的集合,也是个好习惯。
        List<Person> persons = Lists.newArrayListWithExpectedSize(6);
        persons.add(new Person(11, "周星驰"));
        persons.add(new Person(11, "吴孟达"));
        persons.add(new Person(44, "陈世美"));
        persons.add(new Person(44, "小金金--是程咬金的意思,不是潘金莲。。。"));
        persons.add(new Person(22, "潘金莲"));
        persons.add(new Person(22, "武松"));
        persons.add(new Person(33, "阿姆斯特丹"));
        persons.add(new Person(33, "阿姆斯特朗"));

        //可以拿出去,分开声明,然后如下合并一起。代码好看些。
        Ordering<Person> ordering = OrderingConstants.AGE_ORDERING.compound(OrderingConstants.NAME_ORDERING);
        persons.sort(ordering);
        persons.forEach(person -> System.out.println(person.toString()));
    }

大师兄

可以看到结果是,先按照年纪排序,年纪相同了,就按照名称排序,名称排序是按照字母表顺序排的。

猜你喜欢

转载自blog.csdn.net/qq_27093465/article/details/82224203