Guava新集合使用

Guava新集合使用

1-  guava是什麼

guava是Google開源的一個針對Java語言的工具庫,其中包含了null的處理,簡化Throwable異常,集合,緩存,函數式編程,併發,I/O,字符串處理,區間,事件總線,原生類型,數學運算,反射等相關的封裝處理。本文主要介紹Guava引入的新的集合類型,側重點在新集合的使用方法上,幫助開發人員儘快使用Guava進行開發,提高工作效率。

No BB,Show Code!

2-  準備工作

0-引入guava的maven依賴,運行環境JDK1.8

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

1-定義一個javabean,後續介紹新集合時都是盛放這種類型的元素

class Detail {

    private String orderNo;

    private String goodsNo;

    private Integer qty;

    public Detail() {
    }

    public Detail(String orderNo, String goodsNo, Integer qty) {
        this.orderNo = orderNo;
        this.goodsNo = goodsNo;
        this.qty = qty;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getGoodsNo() {
        return goodsNo;
    }

    public void setGoodsNo(String goodsNo) {
        this.goodsNo = goodsNo;
    }

    public Integer getQty() {
        return qty;
    }

    public void setQty(Integer qty) {
        this.qty = qty;
    }

    @Override
    public String toString() {
        return "Detail{" +
                "orderNo='" + orderNo + '\'' +
                ", goodsNo='" + goodsNo + '\'' +
                ", qty=" + qty +
                '}';
    }
}

2-定義一個測試類,初始化一個List<Detail>,代碼如下

public class GuavaCollectionTest {

    private static List<Detail> detailList = Arrays.asList(
            new Detail("10001", "100010001", 1),
            new Detail("10001", "100010002", 2),
            new Detail("10001", "100010003", 3),
            new Detail("10001", "100010003", 4),
            new Detail("20002", "200020004", 5),
            new Detail("20002", "200020005", 6),
            new Detail("20002", "200020009", 7),
            new Detail("20002", "200020009", 8),
            new Detail("30003", "300030006", 9),
            new Detail("30003", "300030007", 1),
            new Detail("30003", "300030008", 2),
            new Detail("30003", "300030008", 3)
    );
}

3-  Guava新集合

3.1MultiMap

MultiMap:可以像使用Map一樣向MultiMap集合中put進<K,V>鍵值對,與Map不同的是,相同的Key,後put進去的不會覆蓋之前的,而是把相同Key對應的多個Value值進入一個Collection集合中,這個Collection集合可以是List也可以是一個Set。

假設現在的業務需求是,處理2中的detailList,要求獲取一個Map,Map的key是detailList中所有存在的orderNo,value是orderNo下所有的goodsNo的Set集合。

先看下傳統的實現方法:

/**
 * 找出orderNo對應的單子下的所有的goodsNo組合成一個Map<key:orderNo,value:goodsNoSet>
 * 傳統的方法:
 * 1-確定orderNo2GoodsNoSetMap是否包含orderNo的key
 * 2-如果包含,則根據orderNo取出orderNo2GoodsNoSetMap對應的value,add進goodsNo
 * 3-如果不包含則new一個goodsNoSet,把goodsNo放入goodsNoSet中,在把Set集合放入Map中
 */
@Test
public void testNormal() {
    Map<String, Set<String>> orderNo2GoodsNoSetMap = new HashMap<>();
    Set<String> goodsNoSet;
    for (Detail detail : detailList) {
        if (!orderNo2GoodsNoSetMap.containsKey(detail.getOrderNo())) {
            goodsNoSet = new HashSet<>();
            goodsNoSet.add(detail.getGoodsNo());
            orderNo2GoodsNoSetMap.put(detail.getOrderNo(), goodsNoSet);
        } else {
            orderNo2GoodsNoSetMap.get(detail.getOrderNo()).add(detail.getGoodsNo());
        }
    }
    printMap(orderNo2GoodsNoSetMap);
}

使用MultiMap的方式:

/**
 * 找出orderNo對應的單子下的所有的goodsNo
 * 使用Guava集合的方式,直接放入Multimap對象中,最後使用asMap方法取出
 */
@Test
public void testGuavaCollection() {
    Multimap<String, String> multimap = HashMultimap.create();
    for (Detail detail : detailList) {
        multimap.put(detail.getOrderNo(), detail.getGoodsNo());
    }
    Map<String, Collection<String>> map = multimap.asMap();
    for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
        entry.getValue().stream().forEach(System.out::println);
    }
}

private static void printMap(Map<String, Set<String>> map) {
    if (null != map && map.size() > 0) {
        for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
            for (String s : entry.getValue()) {
                System.out.println(entry.getKey() + ":" + s);
            }
        }
    }
}

代碼看起來更加清晰,易懂!

3.2BiMap

BiMap實現了從key-value、value-key的雙向映射,具體代碼如下

/**
 * JDK中的HashMap是key到value的映射,實際業務中有時候即需要從key-value的映射
 * 也需要value-key的映射,BiMap就可以實現這樣的功能
 * 需要注意的是BiMap的key是一個Set集合,value也是一個Set集合
 */
@Test
public void testBiMap() {
    BiMap<String, Integer> biMap = HashBiMap.create();
    biMap.put("aa", 1);
    biMap.put("bb", 2);
    biMap.put("cc", 3);
    for (BiMap.Entry<String, Integer> entry : biMap.entrySet()) {
        System.out.println("Key:" + entry.getKey() + ";" + "Value:" + entry.getValue());
    }
    //反轉key-value的映射關係
    BiMap<Integer, String> inverseMap = biMap.inverse();
    for (BiMap.Entry<Integer, String> entry : inverseMap.entrySet()) {
        System.out.println("Key:" + entry.getKey() + ";" + "Value:" + entry.getValue());
    }
    //可以向inverseMap添加Entry
    inverseMap.put(4, "dd");
    //在吧inverseMap反轉回去
    biMap = inverseMap.inverse();
    for (BiMap.Entry<String, Integer> entry : biMap.entrySet()) {
        System.out.println("Key:" + entry.getKey() + ";" + "Value:" + entry.getValue());
    }
}

3.3MultiSet

統計集合中某個元素出現的次數

/**
 * 統計相同元素在集合中出現的次數
 */
@Test
public void testMultiSet() {
    Multiset<String> multiset = HashMultiset.create();
    multiset.add("aa");
    multiset.add("aa");
    multiset.add("aa");
    multiset.add("aa");
    multiset.add("bb");
    //一次性添加多個元素
    multiset.add("cc", 6);
    //統計"aa"出現的次數
    int aa = multiset.count("aa");
    System.out.println("count(aa):" + aa);
    System.out.println("count(cc):" + multiset.count("cc"));
    //multiset轉換成Set集合
    Set<String> strSet = multiset.elementSet();
    strSet.stream().forEach(System.out::println);
    //統計每個詞出現的次數
    Set<Multiset.Entry<String>> entrieSet = multiset.entrySet();
    for (Multiset.Entry<String> entry : entrieSet) {
        System.out.println("Str:" + entry.getElement() + ";Count:" + entry.getCount());
    }
}

3.4Table

Table實現了雙key到一個value的映射關係!

假設現在需要處理detailList,獲取根據orderNo+goodsNo到qty的映射關係,先看傳統方法

/**
 * 需要獲取orderNo+goodsNo到對應qty的映射Map,
 * 下面是傳統方法獲取
 */
@Test
public void testNormal3() {
    Map<String, Integer> orderNoGoodsNo2QtyMap = new HashMap<>();
    for (Detail detail : detailList) {
        orderNoGoodsNo2QtyMap.put(detail.getOrderNo() + "_" + detail.getGoodsNo(), detail.getQty());
    }
    for (Map.Entry<String, Integer> entry : orderNoGoodsNo2QtyMap.entrySet()) {
        String orderNoGoodsNo = entry.getKey();
        String orderNo = orderNoGoodsNo.split("_")[0];
        String goodsNo = orderNoGoodsNo.split("_")[1];
        System.out.println("orderNo:" + orderNo + ";goodsNo:" + goodsNo + ";qty:" + entry.getValue());
    }
}

使用Table集合

/**
 * 傳統的Map是一個key到一個value的映射,但是實際業務中經常需要多個key對應一個value
 * 使用guava新集合的方法,不需要使用一箇中間切割符進行切割,代碼結構更加清晰易懂
 */
@Test
public void testTable() {
    Table<String, String, Integer> table = HashBasedTable.create();
    for (Detail detail : detailList) {
        table.put(detail.getOrderNo(), detail.getGoodsNo(), detail.getQty());
    }
    for (Table.Cell<String, String, Integer> cell : table.cellSet()) {
        System.out.println("orderNo:" + cell.getColumnKey() + ";goodsNo:" + cell.getRowKey() + ";qty:" + cell.getValue());
    }
}

綜上,代碼結構更加清晰易懂!

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