Guava包是我最近項目中同事推薦使用的,是google推出的庫。里面的功能非常多,包括了集合、緩存、原生類型支持、並發庫、通用注解、字符串處理、IO等。我們項目中使用到了guava依賴,但是實際上只是用了其中很小一部分功能,比如集合的聲明和處理以及函數式風格等。
廢話少說,上圖先:
我們會發現里面太多的東西,基本上全部加起來得有數百個上千的類了,但是所經常使用的其實就幾十個類。其實可以在項目中建立common-utils包專門抄一部分guava的類過去,而不必全部將guava依賴進來。
工作中使用最多的莫過於List、set、map、string,I/O了,先看Lists吧。
@GwtCompatible(emulated = true) public final class Lists {}
這個是guava中Lists工具的聲明,這個GwtCompatible的注解有兩個參數,一個是serializable 一個是imulated,都是boolean的值,表示是否需要支持序列化、是否仿真(其實就是是否和JVM的默認實現不一致)。guava中的注釋寫的非常詳細,方法也非常多,但實際上我經常用到的只不過是某些list的聲明和一些將list拆分的功能,所以我就只關心那幾個方法了。上圖看下guava lists類的方法:
其實里面很多方法就是使用泛型簡化平時手工去敲的操作。有些方法在jdk1.7及以后已經應該變成deprecated。
@GwtCompatible(serializable = true) public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) { checkNotNull(elements); // for GWT // Let ArrayList's sizing logic work, if possible return (elements instanceof Collection) ? new ArrayList<E>(Collections2.cast(elements)) : newArrayList(elements.iterator()); }
Lists中newArrayList和newLinkedList等有好幾個重載方法,其實就是使用泛型去簡化一些工作。可能有人疑問我用Lists.newArrayList(xxx)和直接new ArrayList<?>()有什么區別,其實就是省點打字的功夫。比如你創建一個List<Map<String,Map<String,Object>> 這樣子的list,如果你要用new的話得還得費很大勁去敲鍵盤,其實用guava去聲明只需要使用重載方法就行了:
List<Map<String,Map<String,Object>>> list = Lists.newArrayList();
其實后面的創建的LinkedList、copyonwriteArrayList等等如出一轍,就不再多看。
還有一個比較有用的方法是拆分list:
public static <T> List<List<T>> partition(List<T> list, int size) { checkNotNull(list); checkArgument(size > 0); return (list instanceof RandomAccess) ? new RandomAccessPartition<T>(list, size) : new Partition<T>(list, size); }
比如當你需要請求別人的API傳入參數時對方的入參數量有限制,可以先拆分然后順序請求獲得結果。
RandomAccess意思是加快訪問速度,不保證順序但是可以讓所有元素都常量時間拿到。下面列出Partition的詳細代碼:
private static class Partition<T> extends AbstractList<List<T>> { final List<T> list; final int size; Partition(List<T> list, int size) { this.list = list; this.size = size; } @Override public List<T> get(int index) { checkElementIndex(index, size()); int start = index * size; int end = Math.min(start + size, list.size()); return list.subList(start, end); } @Override public int size() { return IntMath.divide(list.size(), size, RoundingMode.CEILING); } @Override public boolean isEmpty() { return list.isEmpty(); } }
也就是當你get的時候,它去進行subList操作。
接下來是一些很小眾的功能了:
@Beta public static ImmutableList<Character> charactersOf(String string) { return new StringAsImmutableList(checkNotNull(string)); }
獲得一個String的不可變Char。
@Beta public static List<Character> charactersOf(CharSequence sequence) { return new CharSequenceAsList(checkNotNull(sequence)); }
獲得一個charsquence的list
@CheckReturnValue public static <T> List<T> reverse(List<T> list) { if (list instanceof ImmutableList) { return ((ImmutableList<T>) list).reverse(); } else if (list instanceof ReverseList) { return ((ReverseList<T>) list).getForwardList(); } else if (list instanceof RandomAccess) { return new RandomAccessReverseList<T>(list); } else { return new ReverseList<T>(list); } }
反轉一個list。
剩下還有很多重寫方法和static的protected的方法,但是都很常見。接下來去看一下Sets類吧。