天天看點

guava快速入門(一)

Guava工程包含了若幹被Google的 Java項目廣泛依賴 的核心庫,例如:集合 [collections] 、緩存 [caching] 、原生類型支援 [primitives support] 、并發庫 [concurrency libraries] 、通用注解 [common annotations] 、字元串處理 [string processing] 、I/O 等等。

guava類似Apache Commons工具集

基本工具包Base

Optional

guava的Optional類似于Java 8新增的Optional類,都是用來處理null的,不過guava的是抽象類,其實作類為Absent和Present,而java.util的是final類。其中一部分方法名是相同的。

Guava用Optional表示可能為null的T類型引用。一個Optional執行個體可能包含非null的引用(我們稱之為引用存在),也可能什麼也不包括(稱之為引用缺失)。它從不說包含的是null值,而是用存在或缺失來表示。但Optional從不會包含null值引用。

import com.google.common.base.Optional;

/**
 * Guava用Optional表示可能為null的T類型引用。
 * 
 * @author LENOVO
 *
 */
public class OptionalDemo {

	public static void main(String[] args) {
		Integer value1 = null;
		Integer value2 = 10;
		/*
		 * 建立指定引用的Optional執行個體,若引用為null則快速失敗傳回absent() absent()建立引用缺失的Optional執行個體
		 */
		Optional<Integer> a = Optional.fromNullable(value1);
		Optional<Integer> b = Optional.of(value2); // 傳回包含給定的非空引用Optional執行個體
		System.out.println(sum(a, b));
	}

	private static Integer sum(Optional<Integer> a, Optional<Integer> b) {
		// isPresent():如果Optional包含非null的引用(引用存在),傳回true
		System.out.println("First param is present: " + a.isPresent());
		System.out.println("Second param is present: " + b.isPresent());
		Integer value1 = a.or(0); // 傳回Optional所包含的引用,若引用缺失,傳回指定的值
		Integer value2 = b.get(); // 傳回所包含的執行個體,它必須存在,通常在調用該方法時會調用isPresent()判斷是否為null
		return value1 + value2;
	}
}
      

 運作傳回:

First param is present: false
Second param is present: true
10
      

  

Preconditions

前置條件Preconditions提供靜态方法來檢查方法或構造函數,被調用是否給定适當的參數。它檢查的先決條件。其方法失敗抛出IllegalArgumentException。

import com.google.common.base.Preconditions;

/**前置條件Preconditions提供靜态方法來檢查方法或構造函數
 * @author LENOVO
 *
 */
public class PreconditionDemo {

	   public static void main(String[] args) {
	       try {
	           getValue(5);
	       } catch (IndexOutOfBoundsException e){
	           System.out.println(e.getMessage());
	       }

	       try {
	           sum(4,null);
	       } catch (NullPointerException e){
	           System.out.println(e.getMessage());
	       }

	       try {
	           sqrt(-1);
	       } catch (IllegalArgumentException e){
	           System.out.println(e.getMessage());
	       }

	   }

	   private static double sqrt(double input){
	       Preconditions.checkArgument(input>0.0,
	               "Illegal Argument passed: Negative value %s.",input);
	       return Math.sqrt(input);
	   }

	   private static int sum(Integer a,Integer b){
	       a=Preconditions.checkNotNull(a,
	               "Illegal Argument passed: First parameter is Null.");
	       b=Preconditions.checkNotNull(b,
	               "Illegal Argument passed: Second parameter is Null.");
	       return a+b;
	   }

	   private static int getValue(int input){
	       int[] data={1,2,3,4,5};
	       int index=Preconditions.checkElementIndex(input,data.length,
	               "Illegal Argument passed: Invalid index.");
	       return data[index];
	   }

}
      

  傳回:

Illegal Argument passed: Invalid index. (5) must be less than size (5)
Illegal Argument passed: Second parameter is Null.
Illegal Argument passed: Negative value -1.0.
      

Joiner

Joiner 提供了各種方法來處理字元串加入操作,對象等。

Joiner的執行個體不可變的,是以是線程安全的。

guava快速入門(一)
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Joiner;

/**Joiner 提供了各種方法來處理字元串加入操作,對象等
 * @author LENOVO
 *
 */
public class JoinerDemo {

	 public static void main(String[] args) {
	       /*
	         on:制定拼接符号,如:test1-test2-test3 中的 “-“ 符号
	         skipNulls():忽略NULL,傳回一個新的Joiner執行個體
	         useForNull(“Hello”):NULL的地方都用字元串”Hello”來代替
	        */
	       StringBuilder sb=new StringBuilder();
	       Joiner.on(",").skipNulls().appendTo(sb,"Hello","guava");
	       System.out.println(sb);
	       System.out.println(Joiner.on(",").useForNull("none").join(1,null,3));
	       System.out.println(Joiner.on(",").skipNulls().join(Arrays.asList(1,2,3,4,null,6)));
	       Map<String,String>map=new HashMap<>();
	       map.put("key1","value1");
	       map.put("key2","value2");
	       map.put("key3","value3");
	       System.out.println(Joiner.on(",").withKeyValueSeparator("=").join(map));
	   }
}
      
Hello,guava
1,none,3
1,2,3,4,6
key1=value1,key2=value2,key3=value3
      

Splitter

Splitter 能夠将一個字元串按照指定的分隔符拆分成可疊代周遊的字元串集合,Iterable

import com.google.common.base.Splitter;

/**Splitter 能夠将一個字元串按照指定的分隔符拆分成可疊代周遊的字元串集合
 * @author LENOVO
 *
 */
public class SplitterDemo {

	  public static void main(String[] args) {
	       /*
	         on():指定分隔符來分割字元串
	         limit():當分割的子字元串達到了limit個時則停止分割
	         fixedLength():根據長度來拆分字元串
	         trimResults():去掉子串中的空格
	         omitEmptyStrings():去掉空的子串
	         withKeyValueSeparator():要分割的字元串中key和value間的分隔符,分割後的子串中key和value間的分隔符預設是=
	        */
	       System.out.println(Splitter.on(",").limit(3).trimResults().split(" a,  b,  c,  d"));//[ a, b, c,d]
	       System.out.println(Splitter.fixedLength(3).split("1 2 3"));//[1 2,  3]
	       System.out.println(Splitter.on(" ").omitEmptyStrings().splitToList("1  2 3"));
	       System.out.println(Splitter.on(",").omitEmptyStrings().split("1,,,,2,,,3"));//[1, 2, 3]
	       System.out.println(Splitter.on(" ").trimResults().split("1 2 3")); //[1, 2, 3],預設的連接配接符是,
	       System.out.println(Splitter.on(";").withKeyValueSeparator(":").split("a:1;b:2;c:3"));//{a=1, b=2, c=3}
	   }

}
      
[a, b, c,  d]
[1 2,  3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
{a=1, b=2, c=3}
      

Objects

java7及以後的版本建議使用jdk中的Objects類

EventBus

Guava為我們提供了事件總線EventBus庫,它是事件釋出-訂閱模式的實作,讓我們能在領域驅動設計(DDD)中以事件的弱引用本質對我們的子產品和領域邊界很好的解耦設計。

Guava為我們提供了同步事件EventBus和異步實作AsyncEventBus兩個事件總線,他們都不是單例的。

Guava釋出的事件預設不會處理線程安全的,但我們可以标注@AllowConcurrentEvents來保證其線程安全

如果Listener A監聽Event A, 而Event A有一個子類Event B, 此時Listener A将同時接收Event A和B消息

事件

/**Guava 釋出-訂閱模式中傳遞的事件,是一個普通的POJO類
 * @author LENOVO
 *
 */
public class OrderEvent { // 事件
	private String message;

	public OrderEvent(String message) {
		this.message = message;
	}

	public String getMessage() {
		return message;
	}
}
      

訂閱

import com.google.common.eventbus.Subscribe;

public class EventListener { // 訂閱者

	// @Subscribe保證有且隻有一個輸入參數,如果你需要訂閱某種類型的消息,隻需要在指定的方法上加上@Subscribe注解即可
	@Subscribe
	public void listen(OrderEvent event) {
		System.out.println("receive message: " + event.getMessage());
	}

	/*
	 * 一個subscriber也可以同時訂閱多個事件 Guava會通過事件類型來和訂閱方法的形參來決定到底調用subscriber的哪個訂閱方法
	 */
	@Subscribe
	public void listen(String message) {
		System.out.println("receive message: " + message);
	}
}
      

多個訂閱者

import com.google.common.eventbus.Subscribe;

public class MultiEventListener {

	@Subscribe
	public void listen(OrderEvent event) {
		System.out.println("receive msg: " + event.getMessage());
	}

	@Subscribe
	public void listen(String message) {
		System.out.println("receive msg: " + message);
	}
}
      

  Demo:

import com.google.common.eventbus.EventBus;

public class EventBusDemo {

	public static void main(String[] args) {
		EventBus eventBus = new EventBus("jack");
		/*
		 * 如果多個subscriber訂閱了同一個事件,那麼每個subscriber都将收到事件通知 
		 * 并且收到事件通知的順序跟注冊的順序保持一緻
		 */
		eventBus.register(new EventListener()); // 注冊訂閱者
		eventBus.register(new MultiEventListener());
		eventBus.post(new OrderEvent("hello")); // 釋出事件
		eventBus.post(new OrderEvent("world"));
		eventBus.post("!");//隻有他才會執行所有的事件
	}

}
      
receive message: hello
receive msg: hello
receive message: world
receive msg: world
receive message: !
receive msg: !
      

DeadEvent

如果EventBus發送的消息都不是訂閱者關心的稱之為Dead Event。

import com.google.common.eventbus.DeadEvent;
import com.google.common.eventbus.Subscribe;

public class DeadEventListener {
	boolean isDelivered = true;

	@Subscribe
	public void listen(DeadEvent event) {
		isDelivered = false;
		System.out.println(event.getSource().getClass() + "  " + event.getEvent()); // source通常是EventBus
	}

	public boolean isDelivered() {
		return isDelivered;
	}
}
      

參考:http://www.importnew.com/tag/guava