Thursday, December 5, 2013

Learning Guava Source Code



Ordering 是一个特殊的Comparator 实例。然而由于其良好的扩展性,可轻轻松构造复杂的comparator,比如加强型的容器的比较、排序等等;同时,Ordering提供链式方法调用,使用代码非常简洁漂亮。
Ordering<String> ordering = Ordering.from(String.CASE_INSENSITIVE_ORDER);
ordering.compare("A", "a")

链式比较

Ordering<String> ordering = Ordering.natural().nullsFirst().reverse().lexicographical().reverse().nullsLast();
ordering.sortedCopy(list);

Collection排序比较

Ordering<String> ordering = = Ordering.nullsFirst().reverse();
Collections.sort(names, ordering);

Ordering 详解

创建排序器

方法描述
natural()对可排序类型做自然排序,如数字按大小,日期按先后排序
usingToString()按对象的字符串形式做字典排序[lexicographical ordering]
from(Comparator)把给定的Comparator转化为排序器

链式调用方法

方法描述
reverse()获取语义相反的排序器
nullsFirst()使用当前排序器,但额外把null值排到最前面
nullsLast()使用当前排序器,但额外把null值排到最后面
compound(Comparator)合成另一个比较器,以处理当前排序器中的相等情况
lexicographical()基于处理类型T的排序器,返回该类型的可迭代对象Iterable<T>的排序器
onResultOf(Function)对集合中元素调用Function,再按返回值用当前排序器排序

运用排序器

方法描述
greatestOf(Iterable iterable, int k)获取可迭代对象中最大的k个元素
isOrdered(Iterable)判断可迭代对象是否已按排序器排序:允许有排序值相等的元素
sortedCopy(Iterable)判断可迭代对象是否已严格按排序器排序:不允许排序值相等的元素
min(E, E)返回两个参数中最小的那个。如果相等,则返回第一个参数
min(E, E, E, E...)返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数
min(Iterable)返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException

链式简洁风的实现原理

  • 基类
基类采用上述静态函数得到实例后,调用自身各种排序算法的接口获取新的排序实例,而接口中采用new子类实例获取,示例如下:
public abstract class Ordering<T> implements Comparator<T> {
    public <S extends T> Ordering<S> reverse() {
        return new ReverseOrdering<S>(this);
      }
    ......
}
  • 子类
子类负责特定的排序算法,示例如下:
final class ReverseOrdering<T> extends Ordering<T> implements Serializable {
     ReverseOrdering(Ordering<? super T> forwardOrder) {
        this.forwardOrder = checkNotNull(forwardOrder);
      }
    ......
}

总结

Guava的Ordering非常好的扩展性,较易扩展为复杂业务的比较器,且提供流行的链式风格,写代码如写文章,读代码如读美文.

Guava overflow detection
public static long checkedAdd(long a, long b) {
long result = a + b;
checkNoOverflow((a ^ b) &lt; 0 | (a ^ result) &gt;= 0); // if false, throw exception
return result;
}

// on overflow in case 1: a,b same sign, 2: a, b different sign, a and result same sign
public static long checkedSubtract(long a, long b) {
long result = a - b;
checkNoOverflow((a ^ b) &gt;= 0 | (a ^ result) &gt;= 0);
return result;
}

public static short checkedCast(long value) {
short result = (short) value;
checkArgument(result == value, "Out of range: %s", value);
return result;
}

Upcasting
https://www.securecoding.cert.org/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow
public static int multAccum(int oldAcc, int newVal, int scale)
                  throws ArithmeticException {
  final long res = intRangeCheck(
   ((long) oldAcc) + intRangeCheck((long) newVal * (long) scale)
  );
  return (int) res; // safe down-cast
}

RangesMatcher
public static final CharMatcher DIGIT = new RangesMatcher(
      "CharMatcher.DIGIT", ZEROES.toCharArray(), NINES.toCharArray());
public boolean matches(char c) {
int index = Arrays.binarySearch(rangeStarts, c);
if (index &gt;= 0) {
return true;
} else {
index = ~index - 1;
return index &gt;= 0 && c &lt;= rangeEnds[index];
}
}

Use bitset 
public static final CharMatcher JAVA_ISO_CONTROL =inRange('\u0000', '\u001f').or(inRange('\u007f', '\u009f'))
static CharMatcher inRange(final char startInclusive, final char endInclusive,
String description) {
return new FastMatcher(description) {
@Override public boolean matches(char c) {
return startInclusive &lt;= c && c &lt;= endInclusive;
}

@GwtIncompatible("java.util.BitSet")
@Override void setBits(BitSet table) {
table.set(startInclusive, endInclusive + 1);
}
};
}

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts