Guava工具包使用

Guava工具包含了若干被Google的 Java項目廣泛依賴 的核心庫,例如:

  1. 集合 [collections]
  2. 緩存 [caching]
  3. 原生類型支持 [primitives support]
  4. 併發庫 [concurrency libraries]
  5. 通用註解 [common annotations]
  6. 字符串處理 [string processing]
  7. I/O 等等

引用

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>26.0</version>
</dependency>

集合:

不可變集合

不可變對象有很多優點,包括:

  • 當對象被不可信的庫調用時,不可變形式是安全的;
  • 不可變對象被多個線程調用時,不存在競態條件問題
  • 不可變集合不需要考慮變化,因此可以節省時間和空間。所有不可變的集合都比它們的可變形式有更好的內存利用率(分析和測試細節);
  • 不可變對象因爲有固定不變,可以作爲常量來安全使用。


JDK也提供了Collections.unmodifiableXXX方法把集合包裝爲不可變形式,但我們認爲不夠好:

  • 笨重而且累贅:不能舒適地用在所有想做防禦性拷貝的場景;
  • 不安全:要保證沒人通過原集合的引用進行修改,返回的集合纔是事實上不可變的;
  • 低效:包裝過的集合仍然保有可變集合的開銷,比如併發修改的檢查、散列表的額外空間,等等。

不可變集合的創建:copyof、of、builder方法、asList 視圖

新集合類型:

  • Multiset:既有ArrayList語義,也有map語義
  • SortedMultiset:支持高效獲取指定範圍的子集
  • Multimap:將一個鍵映射到多個值
  • BiMap:實現鍵值的雙向映射
  • Table:實現表結構,使用多個值做索引
  • ClassToInstanceMap:鍵是類型,值是符合鍵所指類型的對象
ClassToInstanceMap<Number> numberDefaults=MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
  • RangeSet:描述一組不相連的、非空的區間。當添加新的區間時,所有相連的區間會被合併,空區間會被忽略
  • RangeMap:描述了不相交、非空的區間到特定值的映射。不會合並相鄰的映射

 

Collections中未包含的集合工具:

  • Iterables
  • FluentIterable

Lists方法:partition、reverse

集合方法:union、intersection、difference、symmetricDifference、cartesianProduct(返回所有笛卡爾積)、powerSet(所有子集)

Maps方法:

  • uniqueIndex(有一組對象,在某個屬性上分別有獨一無二的值,而希望能夠按照這個屬性值查找對象)
  • index(有一組對象,他們有共同的特定屬性,希望按照這個屬性的值查詢對象,但屬性值不一定是獨一無二的)
  • difference、entriesInCommon、entriesDiffering、entriesOnlyOnLeft、entriesOnlyOnRight
  • invertFrom(Miltimap 多個鍵可以映射到同一個值,invertFrom後也可以將值映射到多個鍵)
  • forMap  把Map包裝成SetMultimap

Table
    transpose  將table表進行轉置

 

集合創建:

// 普通Collection的創建
List<String> list = Lists.newArrayList();
Set<String> set = Sets.newHashSet();
Map<String, String> map = Maps.newHashMap();

// 不變Collection的創建
ImmutableList<String> iList = ImmutableList.of("a", "b", "c");
ImmutableSet<String> iSet = ImmutableSet.of("e1", "e2");
ImmutableMap<String, String> iMap = ImmutableMap.of("k1", "v1", "k2", "v2");
Multiset<String> set1 = HashMultiset.create();
set1.add("a");
set1.add("2");
set1.add("a");

System.out.println("set1 = " + set1.toString());
//計算出現次數
System.out.println("count= " + set1.count("a"));
//key可以重複
Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("a", 1);
multimap.put("a", 1);
System.out.println("multimap = " + multimap);

//雙向map 鍵和值都不能重複
BiMap<String, String> biMap = HashBiMap.create();
biMap.put("a", "1");
biMap.put("b", "2");
System.out.println("bimap key " + biMap.get("a"));
System.out.println("bimap value " + biMap.inverse().get("1"));

//Table 比較常用 <row, column ,value>
Table<String, String, Integer> tables = HashBasedTable.create();
tables.put("row1", "column1",1);
tables.put("row2","column2", 2);
System.out.println("the row1 is " + tables.row("row1"));
System.out.println("the row1 cloumn is " + tables.column("column1"));
System.out.println("the value is " + tables.get("row1", "column1"));

擴展工具類

在元素添加到列表時增加特定行爲

  • Forwarding裝飾器:delegate,覆蓋這個方法返回被裝飾的對象,實現特定行爲
  • PeekingIterator:事先獲取下次next返回的元素
  • AbstractIterator:實現自己的Iterator
  • AbstractSequentialIerator:表示迭代的另一種方式
     

集合的過濾

(1)按照條件過濾

ImmutableList<String> names = ImmutableList.of("begin", "code", "Guava", "Java");
Iterable<String> fitered = Iterables.filter(names, Predicates.or(Predicates.equalTo("Guava"), Predicates.equalTo("Java")));
System.out.println(fitered); // [Guava, Java]

(2)自定義過濾條件

//自定義過濾條件   使用自定義回調方法對Map的每個Value進行操作
ImmutableMap<String, Integer> m = ImmutableMap.of("begin", 12, "code", 15);
        // Function<F, T> F表示apply()方法input的類型,T表示apply()方法返回類型
        Map<String, Integer> m2 = Maps.transformValues(m, new Function<Integer, Integer>() {
            public Integer apply(Integer input) {
                if(input>12){
                    return input;
                }else{
                    return input+1;
                }
            }
        });
System.out.println(m2);   //{begin=13, code=15}

(3)set的交集、並集、差集

HashSet<Integer> setA = Sets.newHashSet(1, 2, 3, 4, 5);
HashSet<Integer> setB = Sets.newHashSet(4, 5, 6, 7, 8);

Sets.SetView<Integer> union = Sets.union(setA, setB);
System.out.println("union:");
for (Integer integer : union){
    System.out.println(integer);//union:12345867
}


Sets.SetView<Integer> difference = Sets.difference(setA, setB);
System.out.println("difference:");
for (Integer integer : difference){
    System.out.println(integer); //difference:123
}


Sets.SetView<Integer> intersection = Sets.intersection(setA, setB);
System.out.println("intersection:");
for (Integer integer : intersection){
    System.out.println(integer);
}

(4)map的交集、並集、差集

Map<String, Integer> mapA = Maps.newHashMap();
Map<String, Integer> mapB = Maps.newHashMap();
mapA.put("a", 1);
mapA.put("b", 2);
mapA.put("c", 6);

mapB.put("d", 4);
mapB.put("c", 3);

MapDifference<String, Integer> difference1 = Maps.difference(mapA, mapB);
System.out.println("are qual " + difference1.areEqual());
System.out.println("diff  " + difference1.entriesDiffering());
System.out.println("left " + difference1.entriesOnlyOnLeft());
System.out.println("right" + difference1.entriesOnlyOnRight());
System.out.println("common" + difference1.entriesInCommon());

字符串操作

(1) 連接器Joiner

將集合轉換爲特定規則的字符串,核心是Joiner類

list->string


List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
String result = Joiner.on(",").join(list);
System.out.println("the string is " + result);

map->String

Map<String, String> map1 = Maps.newHashMap();
map1.put("zhangruizhi", "hehe");
map1.put("zhang", "haha");
String resultMap = Joiner.on(",").withKeyValueSeparator("=").join(map1);
System.out.println("the result map is " + resultMap);

連接器Joiner

Joiner joiner = Joiner.on("; ").skipNulls();
return joiner.join("Harry", null, "Ron", "Hermione");


(2) 拆分器Splitter

將字符串轉換爲特定規則的集合,核心是Splitter類

string->list,可以忽略空格,空行

String s = "192.168.0.1,  192.168.0.2,    192.168.0.3, 192.168.0.4";
List<String> sList = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(s);
System.out.println("the sList is " + sList);

string->map

String mapS = "zhangruizhi=a, zhang=b";
Map<String, String> sMap = Splitter.on(",").withKeyValueSeparator("=").split(mapS);
System.out.println("the s map is " + sMap);

拆分器Splitter

Splitter.on(',')
 
        .trimResults()
 
        .omitEmptyStrings()
 
        .split("foo,bar,,   qux");


字符匹配器CharMatcher

String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字符
String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留數字字符
String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
//去除兩端的空格,並把中間的連續空格替換成單個空格
String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*號替換所有數字
String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
// 只保留數字和小寫字母

字符集Charsets

大小寫格式CaseFormat

CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")); // returns "constantName"

計時工具

Stopwatch stopwatch = Stopwatch.createStarted();
int sum = 0;
for( int i =0; i< 100; i++){
    sum+=i;
}
long time = stopwatch.elapsed(TimeUnit.MICROSECONDS);

文件操作

主要是Files類

File file = new File("/test.txt");
List<String> listTest = null;
try {
    list = Files.readLines(file, Charsets.UTF_8);
} catch (Exception e) {
}

File from = new File("./test.log");
File to = new File("./newFile.log");
File directory = new File("./.");
try{
    Files.copy(from,to);  //複製文件
    Files.move(from, to); //移動文件
    URL url = Resources.getResource("abc.xml"); //獲取classpath根下的abc.xml文件url
}catch (IOException ioe){

}

緩存

Guava Cache適用於:

  • 願意消耗一些內存空間來提升速度。
  • 你預料到某些鍵會被查詢一次以上。
  • 緩存中存放的數據總量不會超出內存容量。
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
 
        .maximumSize(1000)
 
        .expireAfterWrite(10, TimeUnit.MINUTES)
 
        .removalListener(MY_LISTENER)
 
        .build(
 
            new CacheLoader<Key, Graph>() {
 
                public Graph load(Key key) throws AnyException {
 
                    return createExpensiveGraph(key);
 
                }
 
        });

緩存回收:基於容量的回收、定時回收、基於引用的回收、顯式清除


Guava 數學運算

  • Guava Math針對各種不常見的溢出情況都有充分的測試;對溢出語義,Guava文檔也有相應的說明;如果運算的溢出檢查不能通過,將導致快速失敗;
  • Guava Math的性能經過了精心的設計和調優;雖然性能不可避免地依據具體硬件細節而有所差異,但Guava Math的速度通常可以與Apache Commons的MathUtils相比,在某些場景下甚至還有顯著提升;
  • Guava Math在設計上考慮了可讀性和正確的編程習慣;IntMath.log2(x, CEILING) 所表達的含義,即使在快速閱讀時也是清晰明確的。而32-Integer.numberOfLeadingZeros(x – 1)對於閱讀者來說則不夠清晰。

基本使用

Optional

對null值進行快速失敗
Optional<T> 表示可能的null的T類型的引用

Optional.of(T) 創建指定引用的Optional實例,若引用爲null則快速失敗
Optional.absent() 創建引用缺失的Optional實例
Optional.fromNullable(T) 創建指定引用的Optional實例,若引用爲null則表示缺失


 

Preconditions

若干前置條件判斷的方法

checkArgument(boolean) 檢查boolean是否爲true,用來檢查傳遞給方法的參數。 IllegalArgumentException
checkNotNull(T) 檢查value是否爲null,該方法直接返回value,因此可以內嵌使用checkNotNull。 NullPointerException
checkState(boolean) 用來檢查對象的某些狀態。 IllegalStateException
checkElementIndex(int index, int size) 檢查index作爲索引值對某個列表、字符串或數組是否有效。index>=0 && index<size * IndexOutOfBoundsException
checkPositionIndex(int index, int size) 檢查index作爲位置值對某個列表、字符串或數組是否有效。index>=0 && index<=size * IndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size) 檢查[start, end]表示的位置範圍對某個列表、字符串或數組是否有效* IndexOutOfBoundsException

參數檢查 主要是Preconditions類

String testString = null;
Preconditions.checkArgument(!Strings.isNullOrEmpty(testString), "the testString is null or empty");


String testString1 = null;
Preconditions.checkNotNull(testString1);

 

Ordering
用來構建複雜的比較器,完成集合排序的功能

創建排序器:

 

natural() 對可排序類型做自然排序,如數字按大小,日期按先後排序
usingToString() 按對象的字符串形式做字典排序[lexicographical ordering]
from(Comparator) 把給定的Comparator轉化爲排序器



鏈式調用方法:  後面的方法包裝了前面的排序器
 

reverse() 獲取語義相反的排序器
nullsFirst() 使用當前排序器,但額外把null值排到最前面。
nullsLast() 使用當前排序器,但額外把null值排到最後面。
compound(Comparator) 合成另一個比較器,以處理當前排序器中的相等情況。
lexicographical() 基於處理類型T的排序器,返回該類型的可迭代對象Iterable<T>的排序器。
onResultOf(Function) 對集合中元素調用Function,再按返回值用當前排序器排序。


運用排序器:


 

Throwables:簡化異常和錯誤的傳播與檢查

Throwables.propagate  



參考:

https://www.cnblogs.com/peida/archive/2013/06/08/3120820.html
https://wizardforcel.gitbooks.io/guava-tutorial/content/1.html

 

發佈了83 篇原創文章 · 獲贊 30 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章