zoukankan      html  css  js  c++  java
  • Guava CompoundOrdering

    概述

    CompoundOrdering是Ordering的子类,它用来存储比较器链, Ordering的compound()内部实现就是使用

    CompoundOrdering(Comparator<? super T> primary,
                         Comparator<? super T> secondary)

    方法来实现的

    代码

    /** An ordering that tries several comparators in order. */
    @GwtCompatible(serializable = true)
    final class CompoundOrdering<T> extends Ordering<T> implements Serializable {
        final ImmutableList<Comparator<? super T>> comparators;
    
        /**
         * 使用两个比较器组合成一个Ordering
         *
         * @param primary
         * @param secondary
         */
        CompoundOrdering(Comparator<? super T> primary,
                         Comparator<? super T> secondary) {
            this.comparators
                    = ImmutableList.<Comparator<? super T>>of(primary, secondary);
        }
    
        CompoundOrdering(Iterable<? extends Comparator<? super T>> comparators) {
            this.comparators = ImmutableList.copyOf(comparators);
        }
    
        /**
         * 递归并按顺序的调用各个比较器进行比较
         *
         * @param left
         * @param right
         * @return
         */
        @Override public int compare(T left, T right) {
            // Avoid using the Iterator to avoid generating garbage (issue 979).
            // 使用for而不是foreach模式可以避免foreach生成iterator,这样会在每个compare方法结束后造成GC
            // 而且这是一个递归调用方法,如果一个CompoundOrdering拥有n个比较器,调用一次compare就会生成n个
            // iterator,并造成n次垃圾回收
            int size = comparators.size();
            for (int i = 0; i < size; i++) {
                int result = comparators.get(i).compare(left, right);
                if (result != 0) {
                    return result;
                }
            }
            return 0;
        }
    
        /**
         * CompoundOrdering的判等通过comparators来判断
         *
         * @param object
         * @return
         */
        @Override public boolean equals(Object object) {
            if (object == this) {
                return true;
            }
            if (object instanceof CompoundOrdering) {
                CompoundOrdering<?> that = (CompoundOrdering<?>) object;
                return this.comparators.equals(that.comparators);
            }
            return false;
        }
    
        @Override public int hashCode() {
            return comparators.hashCode();
        }
    
        @Override public String toString() {
            return "Ordering.compound(" + comparators + ")";
        }
    
        private static final long serialVersionUID = 0;
    }

    分析

    CompoundOrdering对顺序组合Ordering的实现是使用一个ImmutableList来保存,

    查看代码

            Ordering<String> ordering =
                    Ordering.from(comparator1)
                            .compound(comparator2)
                            .compound(comparator3)
                            .compound(comparator4);

    这个ImmutableList结构图如下

    大概就是一个ImmutableList内会包含一个Ordering和一个Comparator/Ordering, 这样在调用compare方法的时候会使用for循环遍历这个List并递归的调用这些comparator的compare方法,这样就保证了对comparator的顺序调用.另外,值得注意的是compare中取消了遍历器的for写法,而是使用for(int i; ;) 这样的用法,从而避免了大量的生成临时遍历器而影响效率

  • 相关阅读:
    学习java之路2
    学习java之路1
    【JavaSE】如何安装jdk以及java的环境配置(超详细) eclipse的安装和简单使用
    微课堂的使用体验
    Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
    docker概念
    Leetcode103_Binary-tree-zigzag-level-order-traversal
    二叉树广度优先遍历和深度优先遍历
    centos7 安装docker
    yum update 出错
  • 原文地址:https://www.cnblogs.com/zemliu/p/3337625.html
Copyright © 2011-2022 走看看