• [Guava源码分析]Ordering:排序


    我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3876466.html,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。

    API

    实例化

    直接获得 natural() 自然序
    usingToString() 字典序
    指定 from(Comparator) 包装Comparator
    explicit(List) explicit(least, ... others) 指明这几个东西的顺序,只排它们
    直接继承  
    其他 allEqual() 全相等。(稳定排序中)保持原序,可用来把null置后等
    arbitrary() 任意序,似乎没什么意义。对VM周期是不变的。

    继承写法:

    Ordering<String> byLengthOrdering = new Ordering<String>() {
        public int compare(String left, String right) {
            return Ints.compare(left.length(), right.length());
        }
    };

    allEqual用法:

    Ordering.allEqual().nullsLast().asList(t, null, e, s, null, t, null)); 
    //return [t, e, s, t, null, null, null]

    修饰方法

    链式调用

    reverse()  
    nullsFirst()  
    nullsLast()  
    onResultOf(Function) 先应用Function
    lexicographical()  类“字典序”,对于Iterable一位一位比下去

    BreakTie

    compound(Comparator)
    compound(Iterable comparators)

    应用

    min(a,b) min(a,b,c, ...rest) min(Iterator) min(Iterable)   另有max
    leastOf(Iterable, int k) leastOf(Iterator, int k) 最小的k个元素 另有greatestOf
    sortedCopy(Iterable) 返回排好的List 另有immutableSortedCopy
    isOrdered(Iterable) 判断是不是已经有序 另有isStrictlyOrdered

    源码分析

    1. 排序是怎么实现的?

    natural

    NaturalOrdering类
    单例
    compare() 直接调left.compareTo(right)
    另见ReverseNaturalOrdering
    以上两类reverse()方法互相转换。

    toString

    UsingToStringOrdering类
    单例
    compare()两者的toString

    use comparator

    ComparatorOrdering类
    持有一个Comparator实例
    compare()调Comparator

    explicit

    ExplicitOrdering类
    持有一个rankMap
    compare()以rank排序

    others

    AllEqualOrdering类
    单例
    compare()返回0

    ArbitraryOrdering内部类
    单例
    compare()先比较Java给出的hashCode,如冲突用computingMap递增标记(1,2,3,4这样标下去)

    2. 链式调用

    典型的装饰模式,以下每个类都继承自Ordering,同时持有一个Ordering实例(大鱼吃小鱼,小鱼吃虾米)

    Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction)


    先ByFunctionOrdering,调用sortKeyFunction.apply();然后NullsFirstOrdering,处理null;然后NaturalOrdering,调compareTo

    ReverseOrdering类
    compare()内层反向,逆转min、max

    NullsFirstOrdering类
    compare()先处理null,非null再调内层
    另见NullsLastOrdering

    ByFunctionOrdering类
    持有Function
    compare()先调function.apply(),用返回值排

    LexicographicalOrdering类
    compare()一位一位比过去,直到决出胜负或有一边断了

    特殊:

    CompoundOrdering类
    持有一个Comparator List
    compare()用List里的Comparator依次比较

    不要把它跟别的链式调用写在一起。

    3. 怎么找出最大/小的k个元素?

    用到一个特殊算法。但如果要找的元素个数超过总数一半,则不用算法,而是直接排序截取,这样更快。算法适用于k远小n的情况。
    算法流程:
    保持一个2k大小的buffer;每次满了时,清掉较大的一半,剩下k位。
    *剪枝优化:维护一个第k小的阈值,大于它的可以直接忽略了
    *清掉一半的方法:快速选择。定一个标志位,比它小的挪到左边,比它大的挪到右边
    时间O(n + k log k) 存储O(k)

  • 相关阅读:
    第十三次ScrumMeeting会议
    第十二次ScrumMeeting博客
    第十一次ScrumMeeting会议
    Alpha阶段事后分析
    Alpha阶段展示
    Alpha阶段发布说明
    团队项目-第十次scrum 会议
    团队项目-第五次Scrum 会议
    # 团队项目测评博客
    # Beta冲刺前准备
  • 原文地址:https://www.cnblogs.com/hamhog/p/3876466.html
Copyright © 2020-2023  润新知