文档章节

Google Guava 工具集__3__ Ordering犀利的比较器 Object方法

开源中国首席二弟子
 开源中国首席二弟子
发布于 2014/09/06 23:30
字数 1513
阅读 48
收藏 0

Google Guava 工具集 博客栏目链接:Google Guava 博客栏目

博客栏目涉及演示代码 GitHub 地址: 点击打开Guava 演示代码包


Ordering是Guava类库提供的一个犀利强大的比较器工具,Guava的Ordering和JDK Comparator相比功能更强。它非常容易扩展,可以轻松构造复杂的comparator,然后用在容器的比较、排序等操作中。

  本质上来说,Ordering 实例无非就是一个特殊的Comparator 实例。Ordering只是需要依赖于一个比较器(例如,Collections.max)的方法,并使其可作为实例方法。另外,Ordering提供了链式方法调用和加强现有的比较器。

Comparator, Comparable区别

/*
     * Comparator, Comparable区别
     * <p>
     * 1.comparable是通用的接口,用户可以实现它来完成自己特定的比较,
     *      而comparator可以看成一种算法的实现,在需要容器集合 collection需要比较功能的时候,来指定这个比较器。
     * 2.一个类实现了Camparable接口表明这个类的对象之间是可以相互比较的。
     *      如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用Sort方法排序了。
     * 3.而Comparator的作用有两个:
     *  a,如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序
     *  b,可以更加灵活实现排序规则,为了使用不同的排序标准做准备,比如:升序、降序,或者将来想通过类的其他字段进行排序
     *
     * 例如:在对List 排序时候默认使用comparable的compareTo(Object o)方法
     *      但在比较某个对象下的属性时候,我们可以自定义一个Comparator的compare(Object o1, Object o2)方法比较器进行比较
     *      Collections 中的 public static <T> void sort(List<T> list, Comparator<? super T> c) 方法
     *
     */
    private class ComparableAndComparatorDistinction implements Comparator, Comparable {

        /*
         * 重写Comparable中的方法
         */
        @Override
        public int compareTo(Object o) {
            return 0;
        }

        /*
         * 重写Comparator中的方法
         */
        @Override
        public int compare(Object o1, Object o2) {
            return 0;
        }
    }



Ordering犀利的比较器

   



代码演示


package com.framework_technology.commons.google.base;

import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

/**
 * 部分Object 方法
 * <p>
 * Ordering犀利的比较器
 *
 * @author wei.Li by 14-8-27.
 */
public class ObjectMethodsAndOrdering {

    /**
     * 当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查。
     * 使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。
     * <p>
     * 注意:JDK7引入的Objects类提供了一样的方法Objects.equals。
     */
    private static void objectsEqual() {
        Objects.equal("a", "a"); // returns true
        Objects.equal(null, "a"); // returns false
        Objects.equal("a", null); // returns false
        Objects.equal(null, null); // returns true

        Objects.hashCode("a", "b");//
    }

    /**
     * 用对象的所有字段作散列[hash]运算应当更简单。
     * Guava的Objects.hashCode(Object...)会对传入的字段序列计算出合理的、顺序敏感的散列值。
     * 你可以使用Objects.hashCode(field1, field2, …, fieldn)来代替手动计算散列值。
     * <p>
     * 注意:JDK7引入的Objects类提供了一样的方法Objects.hash(Object...)
     */
    private static void objectsHashCode() {
        Objects.equal("a", "a"); // returns true
        Objects.equal(null, "a"); // returns false
        Objects.equal("a", null); // returns false
        Objects.equal(null, null); // returns true

        Objects.hashCode("a", "b");//
    }


    /**
     * 实现一个比较器[Comparator]
     * JDK 与 Guava的实现的不同
     */
    private class Person2compareToTest implements Comparable<Person2compareToTest> {
        private String lastName;
        private String firstName;
        private int zipCode;

        /**
         * jdk 方式的比较
         *
         * @param other
         * @return
         */
        @Override
        public int compareTo(Person2compareToTest other) {
            int cmp = lastName.compareTo(other.lastName);
            if (cmp != 0) {
                return cmp;
            }
            cmp = firstName.compareTo(other.firstName);
            if (cmp != 0) {
                return cmp;
            }
            return Integer.compare(zipCode, other.zipCode);
        }

        /**
         * Guava的实现
         * <p>
         * ComparisonChain执行一种懒比较:它执行比较操作直至发现非零的结果,在那之后的比较输入将被忽略。
         *
         * @param that 比较对象
         * @return 比较结果
         * @see #compareTo(Person2compareToTest)
         */
        public int compareToByComparisonChain(Person2compareToTest that) {
            return ComparisonChain.start()
                    .compare(this.lastName, that.lastName)
                    .compare(this.firstName, that.firstName)
                    .compare(this.zipCode, that.zipCode, Ordering.natural().nullsLast())
                    .result();
        }
    }


    /**
     * Ordering犀利的比较器演示
     * <p>
     * jdk8也实现了部分
     *
     * @see java.util.Comparators
     */
    private static class OrderTest implements Comparable<OrderTest> {

        private int id;
        private String name;

        public static final OrderTest[] ORDER_TESTS = new OrderTest[]{
                new OrderTest(1, "yiwa")
                , new OrderTest(11, "yiwa")
                , new OrderTest(2, "erwa")
                , new OrderTest(3, "sanwa")
                , new OrderTest(4, "siwa")
                , new OrderTest(5, "wuwa")
                , new OrderTest(5, "wuwa")
                , new OrderTest(6, null)
        };

        OrderTest(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public int compareTo(OrderTest that) {
            return ComparisonChain.start()
                    // .compare(this.id, that.id)
                    .compare(this, that, getOrdering())
                    .result()
                    ;
        }

        /**
         * 构建Ordering
         */
        private static Ordering<OrderTest> getOrdering() {

            return Ordering
                    .natural()
                    .nullsFirst()
                            //返回按String 排序的Comparable
                            //当阅读链式调用产生的排序器时,应该从后往前读。
                            // 下面的例子中,排序器首先调用apply方法获取name值,并把name为null的元素都放到最前面,然后把剩下的元素按name进行自然排序。
                            // 之所以要从后往前读,是因为每次链式调用都是用后面的方法包装了前面的排序器。
                    .onResultOf(new Function<OrderTest, Comparable>() {
                        @Override
                        public Comparable apply(OrderTest input) {
                            return input.name;
                        }
                    })
                    // .leastOf(Arrays.asList(ORDER_TESTS),2)
                    ;
        }


        /**
         * 运用选择器进行一些计算
         */
        private static void appleOrdering() {
            Ordering ordering = getOrdering();
            List<OrderTest> orderTestList
                    = Lists.newArrayList(ORDER_TESTS);

            //判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
            boolean orderingOrdered = ordering.isOrdered(orderTestList);
            LOGGER.info("isOrdered          : <{}>", orderingOrdered);

            //判断可迭代对象是否已按排序器严格排序:不允许有排序值相等的元素。
            boolean orderingStrictlyOrdered = ordering.isStrictlyOrdered(orderTestList);
            LOGGER.info("isStrictlyOrdered  : <{}>", orderingStrictlyOrdered);

            //返回指定的元素作为一个列表的排序副本。immutableSortedCopy返回不可变的排序副本
            // LOGGER.info("sortedCopy  : <{}>", ordering.sortedCopy(orderTestList));

            //最大的2元素
            LOGGER.info("greatestOf 2 index : <{}>", ordering.greatestOf(orderTestList, 4));

            //获取最大值,迭代比较大小后返回
            LOGGER.info("orderTestList max  : <{}>", ordering.max(orderTestList));
        }

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

    }

    private static final org.slf4j.Logger LOGGER
            = LoggerFactory.getLogger(Optional_.class);

    public static void main(String[] args) {

        Arrays.sort(OrderTest.ORDER_TESTS);
        LOGGER.info("---------- ORDER_TESTS after sort start ----------");
        for (OrderTest orderTest : OrderTest.ORDER_TESTS) {
            LOGGER.info("<{}>", orderTest);
        }
        LOGGER.info("---------- ORDER_TESTS after sort end   ----------");

        LOGGER.info("\n---------- Apple Ordering start ----------");
        OrderTest.appleOrdering();
        LOGGER.info("---------- Apple Ordering end   ----------");

        /* main 函数执行结果
        ---------- ORDER_TESTS after sort start ----------
<OrderTest{id=6, name='null'}>
<OrderTest{id=2, name='erwa'}>
<OrderTest{id=3, name='sanwa'}>
<OrderTest{id=4, name='siwa'}>
<OrderTest{id=5, name='wuwa'}>
<OrderTest{id=5, name='wuwa'}>
<OrderTest{id=1, name='yiwa'}>
<OrderTest{id=11, name='yiwa'}>
---------- ORDER_TESTS after sort end   ----------

---------- Apple Ordering start ----------
isOrdered          : <true>
isStrictlyOrdered  : <false>
greatestOf 2 index : <[OrderTest{id=1, name='yiwa'}, OrderTest{id=11, name='yiwa'},
                      OrderTest{id=5, name='wuwa'}, OrderTest{id=5, name='wuwa'}]>
orderTestList max  : <OrderTest{id=1, name='yiwa'}>
---------- Apple Ordering end   ----------

         */
    }
}


© 著作权归作者所有

开源中国首席二弟子
粉丝 2
博文 20
码字总数 33047
作品 0
朝阳
程序员
私信 提问
Ordering犀利的比较器(6)

 Ordering是Guava类库提供的一个犀利强大的比较器工具,Guava的Ordering和JDK Comparator相比功能更强。它非常容易扩展,可以轻松构造复杂的comparator,然后用在容器的比较、排序等操作中。...

十二缸帕萨特
2015/10/07
84
0
Guava学习笔记 第4个记录(Ordering犀利的比较器)

Ordering是Guava类库提供的一个犀利强大的比较器工具,Guava的Ordering和JDK Comparator相比功能更强。它非常容易扩展,可以轻松构造复杂的comparator,然后用在容器的比较、排序等操作中。 ...

heroShane
2014/02/12
76
0
google guava基本操作认识 二

避免空指针 "Null sucks." -Doug Lea "I call it my billion-dollar mistake." - Sir C. A. R. Hoare, on his invention of the null reference 1 粗心使用了null导致了很多bug ,迅速失败而不......

writeademo
2018/11/26
16
0
Guava 2:Basic utilities基本工具

一、引子 Guava的经典很大一部分原因来源于对于基础工具类的封装,使用这些类能够让我们的代码更加优雅且完善,这些类大部分都在com.google.common.base包下。 注:JDK有很多借鉴guava的地方...

只会一点java
2018/07/25
0
0
Guava一些高效类的使用实践

guava是google的一个强大的工具包,目前已经更新到版本22 https://github.com/google/guava,一直有断断续续的用过一些方法,但是没有系统的撸一遍所有功能 今天参考并发编程网记录一些高效的...

zimingforever
2017/06/15
152
0

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL 11.3 locking

rudi
今天
5
0
Mybatis Plus sql注入器

一、继承AbstractMethod /** * @author beth * @data 2019-10-23 20:39 */public class DeleteAllMethod extends AbstractMethod { @Override public MappedStatement injectMap......

一个yuanbeth
今天
11
1
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
今天
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
今天
9
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
今天
81
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部