GUAVA經常使用方法總結整理(eventBus)

EventBus事件驅動模型java

在軟件開發過程當中, 不免有信息的共享或者對象間的協做。 如何讓對象間信息共享高效, 而且耦合性低, 這是一個難題。 而耦合性高將帶來編碼修改牽一髮而動全身的連鎖效應, Spring的風靡正是由於解決了高耦合問題。 本篇介紹的EventBus中也用到了Spring中的依賴注入, 來進行對象和對象間的解耦(如@Subscribe)。數組

 

Guava解決高耦合採用的是事件驅動模型的思路, 對象能夠訂閱(subscribe)特定的事件或者發佈(publish)特定的事件去被消費。 從下面的代碼能夠看出, EventBus對生產者和消費者是透明的, 它無需知道他們的類型, 從而實現瞭解耦。app

TradeAccountEvent: 基本對象兼測試類  ide

package com.wenniuwuren.eventbus;
import com.google.common.eventbus.EventBus;
import java.util.Date;
/**
 *  無論何時買賣交易執行, 都會產生一個TradeAccountEvent實例
 */
public class TradeAccountEvent {
    private double amount;
    private Date tradeExecutionTime;
    private String tradeType;
    private String tradeAccount;
    public TradeAccountEvent(String account, double amount,
                             Date tradeExecutionTime, String tradeType) {
        this.amount = amount;
        this.tradeExecutionTime =tradeExecutionTime;
        this.tradeAccount = account;
        this.tradeType = tradeType;
    }
    public static void main(String[] args) {
        // 消費者和生產者根據EventBus對象來一一對應
        EventBus eventBus1 = new EventBus();
        SimpleTradeAuditor simpleTradeAuditor = new SimpleTradeAuditor(eventBus1);
        SimpleTradeExecutor simpleTradeExecutor = new SimpleTradeExecutor(eventBus1);
        simpleTradeExecutor.executeTrade("zhangsan", 10, "Money");
        
        System.out.println("----This is devil dividing line------");
        
        EventBus eventBus2 = new EventBus();
        BuySellTradeExecutor buySellTradeExecutor = new BuySellTradeExecutor(eventBus2);
        AllTradesAuditor allTradesAuditor = new AllTradesAuditor(eventBus2);
        buySellTradeExecutor.executeTrade("lisi", 100, "SELL");
        System.out.println("---------------------");
        buySellTradeExecutor.executeTrade("wangwu", 1000, "BUY");
    }
}

AllTradesAuditor:根據不一樣生產者訂閱不一樣內容:post

package com.wenniuwuren.eventbus;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class AllTradesAuditor {
	private List<BuyEvent> buyEvents = Lists.newArrayList();
	private List<SellEvent> sellEvents = Lists.newArrayList();
	public AllTradesAuditor(EventBus eventBus) {
		eventBus.register(this);
	}
	@Subscribe
	public void auditSell(SellEvent sellEvent) {
		sellEvents.add(sellEvent);
		System.out.println("Received TradeSellEvent " + sellEvent);
	}
	@Subscribe
	public void auditBuy(BuyEvent buyEvent) {
		buyEvents.add(buyEvent);
		System.out.println("Received TradeBuyEvent " + buyEvent);
	}
}

BuyEvent:測試

package com.wenniuwuren.eventbus;
import java.util.Date;
/**
 * 購買事件
 * @author wenniuwuren
 *
 */
public class BuyEvent extends TradeAccountEvent {
	public BuyEvent(String tradeAccount, double amount,
			Date tradExecutionTime) {
		super(tradeAccount, amount, tradExecutionTime, "BUY");
	}
}

SellEvent:ui

package com.wenniuwuren.eventbus;
import java.util.Date;
/**
 * 銷售事件
 * @author wenniuwuren
 *
 */
public class SellEvent extends TradeAccountEvent {
	public SellEvent(String tradeAccount, double amount, Date tradExecutionTime) {
		super(tradeAccount, amount, tradExecutionTime, "SELL");
	}
}

BuySellTradeExecutor: 分類型(BUY、SELL)發佈事件this

package com.wenniuwuren.eventbus;
import java.util.Date;
import com.google.common.eventbus.EventBus;
/**
 * 分類型(SELL BUY)執行器
 * @author wenniuwuren
 *
 */
public class BuySellTradeExecutor {
	private EventBus eventBus;
    public BuySellTradeExecutor(EventBus eventBus) {
        this.eventBus = eventBus;
    }
	
	private TradeAccountEvent processTrade(String tradeAccount, double amount,
			String tradeType) {
		Date executionTime = new Date();
		String message = String.format("Processed trade for" + tradeAccount
				+ "of amount" + amount + "type" + tradeType + "@"
				+ executionTime);
		TradeAccountEvent tradeAccountEvent;
		if (tradeType.equals("BUY")) {
			tradeAccountEvent = new BuyEvent(tradeAccount, amount,
					executionTime);
		} else {
			tradeAccountEvent = new SellEvent(tradeAccount, amount,
					executionTime);
		}
		System.out.println(message);
		return tradeAccountEvent;
	}
	
	public void executeTrade(String tradeAccount, double amount, String tradeType) {
        TradeAccountEvent tradeAccountEvent = processTrade(tradeAccount, amount, tradeType);
        // 發佈, 通知訂閱者
        eventBus.post(tradeAccountEvent);
    }
}

SimpleTradeAuditor: 最簡單的事件消費者(或者說訂閱者)google

package com.wenniuwuren.eventbus;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import java.util.List;
/**
 * 審覈交易
 */
public class SimpleTradeAuditor {
    private List<TradeAccountEvent> tradeEvents = Lists.newArrayList();
    public SimpleTradeAuditor(EventBus eventBus) {
        // 註冊, 以便獲取TradeAccountEvent的通知
        eventBus.register(this);
    }
    /**
     * 事件處理(用@Subscribe註解表示)
     * @param tradeAccountEvent
     */
    @Subscribe
    public void auditTrade(TradeAccountEvent tradeAccountEvent) {
        tradeEvents.add(tradeAccountEvent);
        System.out.println("Received trade " + tradeAccountEvent);
    }
}

TradeBuyAuditor:分類型事件消費:編碼

package com.wenniuwuren.eventbus;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
/**
 * 購買審查
 * @author wenniuwuren
 *
 */
public class TradeBuyAuditor {
	private List<BuyEvent> buyEvents = Lists.newArrayList();
	public TradeBuyAuditor(EventBus eventBus) {
		eventBus.register(this);
	}
	@Subscribe
	public void auditBuy(BuyEvent buyEvent) {
		buyEvents.add(buyEvent);
		System.out.println("Received TradeBuyEvent " + buyEvent);
	}
	public List<BuyEvent> getBuyEvents() {
		return buyEvents;
	}
}

TradeSellAuditor:

package com.wenniuwuren.eventbus;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
/**
 * 銷售審查
 * @author wenniuwuren
 *
 */
public class TradeSellAuditor {
	private List<SellEvent> sellEvents = Lists.newArrayList();
	public TradeSellAuditor(EventBus eventBus) {
		eventBus.register(this);
	}
	@Subscribe
	public void auditSell(SellEvent sellEvent) {
		sellEvents.add(sellEvent);
		System.out.println("Received SellEvent " + sellEvent);
	}
	public List<SellEvent> getSellEvents() {
		return sellEvents;
	}
}

輸出結果:

Processed trade forzhangsanof amount10.0typeMoney@Fri Jun 12 02:29:03 CST 2015
Received trade com.wenniuwuren.eventbus.TradeAccountEvent@7c53a9eb
----This is devil dividing line------
Processed trade forlisiof amount100.0typeSELL@Fri Jun 12 02:29:03 CST 2015
Received TradeSellEvent com.wenniuwuren.eventbus.SellEvent@14899482
---------------------
Processed trade forwangwuof amount1000.0typeBUY@Fri Jun 12 02:29:03 CST 2015
Received TradeBuyEvent com.wenniuwuren.eventbus.BuyEvent@21588809

FluentIterable類:

使用FluentIterable.filter過濾, 即利用Predicate實現:

Iterable<Person> adults = FluentIterable.from(ps).filter(
    new Predicate<Person>() {
        @Override
        public boolean apply(Person p) {
            return p.getAge() >= 18; // 年齡>18
        }
    });

使用FluentIterable.transform()轉換,即利用Function實現

FluentIterable.from(ps).transform(new Function<Person, String>() {
	@Override
	public String apply(Person p) {
	     return Joiner.on('#').join(p.getName(), p.getAge());
	}
});

Lists類

使用Lists.newArrayList建立列表:

ps = Lists.newArrayList(
    new Person("person1", 22),
    new Person("person2", 23),
    new Person("person3", 17)
);

使用Lists.partition()方法分割列表:

//[a, b, c, d, e] --> [[a, b], [c, d, e]] -
List<List<Person>> subList = Lists.partition(ps, 2);

Sets類:

Sets.difference()求S1-S2
Set<String> s1 = Sets.newHashSet("1", "2", "3");
Set<String> s2 = Sets.newHashSet("2", "3", "4");
Sets.difference(s1, s2); //[1]

Sets.intersection()求S1,S2交集

Set<String> s1 = Sets.newHashSet("1", "2", "3");
Set<String> s2 = Sets.newHashSet("3", "2", "4");
Sets.SetView<String> sv = Sets.intersection(s1, s2); // [2, 3]

Sets.union()求合集

Set<String> s1 = Sets.newHashSet("1", "2", "3");
Set<String> s2 = Sets.newHashSet("3", "2", "4");
Sets.SetView<String> sv = Sets.union(s1, s2); // [3, 2, 1 ,4]

Maps類:

Maps.uniqueIndex()將列表轉換爲map:

//iterator各個元素做爲Map.values, key爲Function.apply返回值
Maps.uniqueIndex(ps.iterator(), new Function<Person, String>() {
	@Override
	public String apply(Person p) {
		return p.getName();
	}
});

Maps.asMap(),<K, V>和Maps.uniqueIndex()相反

Maps.asMap(ps, new Function<Person, String>() {
	@Override
	public String apply(Person p) {
		return p.getName();
	}
});

Maps Transform API:

將Map<String, Boolean> --> Map<String, String>, 其餘的還有Maps.transformValues轉換值

Maps.transformEntries(map, new Maps.EntryTransformer<String, Boolean, String>() {
    @Override
    public String transformEntry(String key, Boolean value) {
        return value ? "yes" : "no";
    }
});

Multimaps:

一個key對應多個value。

ArrayListMultiMap:

ArrayListMultimap<String, String> multiMap = ArrayListMultimap.create();
multiMap.put("Foo", "1");
multiMap.put("Foo", "2");
multiMap.put("Foo", "3");
System.out.println(multiMap); // {Foo=[1,2,3]}

當出現重複值時,依然會被添加,由於ArrayListMultiMap的value時一個ArrayList:

ArrayListMultimap<String, String> multiMap = ArrayListMultimap.create();
multiMap.put("Bar", "1");
multiMap.put("Bar", "2");
multiMap.put("Bar", "3");
multiMap.put("Bar", "3");
multiMap.put("Bar", "3");
System.out.println(multiMap); //{Bar=[1, 2, 3, 3, 3]},相同的value會重複,value內部是一個List

HashMultiMap:

HashMultimap<String, String> multiMap = HashMultimap.create();
multiMap.put("Bar", "1");
multiMap.put("Bar", "2");
multiMap.put("Bar", "3");
multiMap.put("Bar", "3");
multiMap.put("Bar", "3");
System.out.println(multiMap); //{Bar=[3, 2, 1]}, 相同的value不會重複,value內部是一個Set

其餘一些MultiMap:

LinkedHashMultimap //順序的HashMultimap, 形如LinkedHashMap
TreeMultimap //可排序的MultiMap, 形如TreeMap
//一些不可變的map
ImmutableListMultimap
ImmutableMultimap
ImmutableSetMultimap

BiMap:

其限制value是惟一的,且經過value能夠找到key

BiMap<String,String> biMap = HashBiMap.create();
biMap.put("1","Tom");         
biMap.put("2","Tom"); //拋出異常

BiMap.forcePut()強制放入value相等的entry:

BiMap<String, String> biMap = HashBiMap.create();
biMap.put("1", "Tom");
biMap.forcePut("2", "Tom");
System.out.println(biMap); //{2=Tom}

BiMap.inverse()反轉key-value

BiMap<String, String> biMap = HashBiMap.create();
biMap.put("1", "Tom");
biMap.put("2", "Harry");
BiMap<String, String> inverseMap = biMap.inverse();
System.out.println(biMap); //{2=Harry, 1=Tom}
System.out.println(inverseMap); //{Harry=2, Tom=1

Table:

它具備2個key[行, 列],對應一個值。

HashBasedTable:

通用操做:

HashBasedTable<Integer, Integer, String> table = HashBasedTable.create();
table.put(1, 1, "Rook");
table.put(1, 2, "Knight");
table.put(1, 3, "Bishop");
System.out.println(table.contains(1, 1)); //true
System.out.println(table.containsColumn(2)); //true
System.out.println(table.containsRow(1)); //true
System.out.println(table.containsValue("Rook")); //true
System.out.println(table.remove(1, 3)); //Bishop
System.out.println(table.get(3, 4)); //null

Table views,錶行列視圖:

Map<Integer,String> columnMap = table.column(1);
Map<Integer,String> rowMap = table.row(2);

其餘table:

ArrayTable //二維數組實現
ImmutableTable //不可變table,建立後不能改變
TreeBasedTable //對行列排序的table

Range表明一種範圍的類。:

Range<Integer> numberRange = Range.closed(1, 10); //包括首尾
System.out.println(numberRange.contains(10)); //true
System.out.println(numberRange.contains(1)); //true
		
Range<Integer> numberRange1 = Range.open(1,10); //除去首尾
System.out.println(numberRange1.contains(10)); //false
System.out.println(numberRange1.contains(1)); //false

Range和Function組合成Predicate的過濾條件:

Range<Integer> ageRange = Range.closed(35, 50);
//Person到age轉換的function
Function<Person, Integer> ageFunction = new Function<Person, Integer>() {
	@Override
	public Integer apply(Person person) {
		return person.getAge();
	}
};

//這樣獲得年齡再[35, 50]之間的人

Predicate<Person> predicate = Predicates.compose(ageRange,ageFunction);

建立不可變的集合:

ultiMap<Integer,String> map = new ImmutableListMultimap.Builder<Integer,String>()
                                   .put(1,"Foo").putAll(2,"Foo","Bar","Baz")
                                   .putAll(4,"Huey","Duey","Luey")
                                   .put(3,"Single").build();

Ordering:Ordering提供了一些簡單強大的排序功能。:

/**
 * 城市人口比較器
 */
public class CityByPopluation implements Comparator<City> {
	@Override
	public int compare(City city1, City city2) {
		return Ints.compare(city1.getPopulation(), city2.getPopulation());
	}
}

反序:

Ordering.from(cityByPopluation).reverse();

處理Null:

Ordering.from(comparator).nullsFirst();//null值最小放在前面

二次排序:

/**
 * 雨量比較器
 */
public class CityByRainfall implements Comparator<City> {
	@Override
	public int compare(City city1, City city2) {
		return Doubles.compare(city1.getAverageRainfall(),
				city2.getAverageRainfall());
	}
}
Ordering<City> secondaryOrdering = Ordering.from(cityByPopulation).compound(cityByRainfall);//組合比較器
Collections.sort(cities,secondaryOrdering); //排序

獲取最大最小:

Ordering<City> ordering = Ordering.from(cityByPopluation);
List<City> topFive = ordering.greatestOf(cityList,5); //前5個
List<City> bottomThree = ordering.leastOf(cityList,3); //最後3個
相關文章
相關標籤/搜索