1. 程式人生 > >Java8學習筆記(5) -- 寫給Guava使用者

Java8學習筆記(5) -- 寫給Guava使用者

Guava

Guava是Google公司開源的一個實用工具庫,對Java類庫進行了多方面的增強。比如說,對函數語言程式設計的支援,新的集合類(Multimap等),Cache支援,等等。在Java8之前,Guava和Java之間的關係,可以表示成下面這幅圖:


但是隨著Java8的釋出,Guava和Java的關係發生了一些改變。Guava提供的很多功能,被內建在了Java8裡,如下圖所示:

本文舉了幾個例子,用程式碼來說明原先需要藉助Guava來實現的功能,如何用Java7或Java8實現。

Joiner

Joiner用來拼接n個字串,下面是一個例子:

    @Test
    public void joinerGuava() {
        List<String> strList = Arrays.asList("one", "two", "three", null);
        String csv = Joiner.on(",")
                .skipNulls()
                .join(strList);
        assertEquals("one,two,three", csv);
    }
在Java8裡,我們可以藉助Lambda表示式來做同樣的事情:
    @Test
    public void joinerJava8() {
        List<String> strList = Arrays.asList("one", "two", "three", null);
        String csv = strList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
        assertEquals("one,two,three", csv);
    }

Ordering

Guava提供了Ordering類以方便我們建立Comparator,下面是一段示例程式碼:

    class Player {
        
        private String name;
        
        public String getName() {
            return name;
        }
        
    }
    public void orderingGuava() {
        // public abstract class Ordering<T> implements Comparator<T>
        Ordering<Player> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<Player, String>() {
            @Override
            public String apply(Player foo) {
                return foo.getName();
            }
        });
    }
在Java8裡,我們可以這樣做:
    public void comparingJava8() {
        Comparator<Player> cmp = Comparator.comparing(Player::getName,
                Comparator.nullsFirst(Comparator.naturalOrder()));
    }

Optional

Optional可以顯式的指出一個引用可能是null,下面是從Guava文件裡抄到的例子:

// Guava
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
java.util.Optional可以做類似的事情,而且方法也大同小異,這裡就不貼程式碼了。

Preconditions.checkNotNull()

如果想保證一個引用不是null(儘早丟擲NullPointerException),可以像下面這樣寫:

    class Player {
        
        private final String name;
        
        public Player(String name) {
            this.name = Preconditions.checkNotNull(name);
        }
        
    }

checkNotNull()方法一共有三個版本:

public static <T> T checkNotNull(T reference)
public static <T> T checkNotNull(T reference, Object errorMessage)
public static <T> T checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs)
java.util.Objects提供了三個類似的方法:
public static <T> T requireNonNull(T obj) // @since 1.7
public static <T> T requireNonNull(T obj, String message) // @since 1.7
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) // @since 1.8

Guava Objects

com.google.common.base.Objects類裡的一些方法,可以替換成java.util.Objects裡的方法,比如:

// com.google.common.base.Objects
public static boolean equal(@Nullable Object a, @Nullable Object b)
public static int hashCode(@Nullable Object... objects)
可以用下面的方法替換:
// java.util.Objects
public static boolean equals(Object a, Object b) // @since 1.7
public static int hashCode(Object o) // @since 1.7
public static int hash(Object... values) // @since 1.7

函數語言程式設計

很多人使用Guava的直接原因,可能就是想更好的進行函數語言程式設計。為了支援函數語言程式設計,Guava提供了下面這兩個介面:

public interface Function<F, T> {
    @Nullable T apply(@Nullable F input);
}
public interface Predicate<T> {
    boolean apply(@Nullable T input);
}

Guava的各種集合幫助類都提供了大量使用上面兩個介面的方法,比如Iterables、Collections2、Maps等等。但是Guava的函數語言程式設計,仍然是建立在Java匿名類的語法之上,雖然一定程度上降低了程式碼的醜陋程度,但是仍然不夠理想。Java8的出現,徹底讓Guava的函數語言程式設計變的多餘。

Multimap

假設我們想按照玩家的groupId來給玩家分組,Java8以前,可以這樣做:

    public void mapListJava7(List<Player> players) {
        Map<Integer, List<Player>> groups = new HashMap<>();
        for (Player player : players) {
            List<Player> group = groups.get(player.getGroupId());
            if (group == null) {
                group = new ArrayList<>();
                groups.put(player.getGroupId(), group);
            }
            group.add(player);
        }
    }
如果用Guava的Multimap,程式碼就會清晰很多:
    public void guavaMultimap(List<Player> players) {
        Multimap<Integer, Player> groups = ArrayListMultimap.create();
        for (Player player : players) {
            groups.put(player.getGroupId(), player);
        }
    }

Java8給Map添加了getOrDefault()方法,所以即使不用Lambda,程式碼也會簡單一點:

    public void mapListJava8(List<Player> players) {
        Map<Integer, List<Player>> groups = new HashMap<>();
        for (Player player : players) {
            List<Player> group = groups.getOrDefault(player.getGroupId(), new ArrayList<>());
            group.add(player);
        }
    }

當然,可以用Lambda表示式來更清晰的表達意圖:

    public void groupingByJava8(List<Player> players) {
        Map<Integer, List<Player>> groups = players.stream()
                .collect(Collectors.groupingBy(Player::getGroupId));
    }

結論

Guava是一個很好的庫,但是隨著Java自身的改進,Guava的很多功能已經變得多餘。

相關推薦

Java8學習筆記5 -- Guava使用者

Guava Guava是Google公司開源的一個實用工具庫,對Java類庫進行了多方面的增強。比如說,對函數語言程式設計的支援,新的集合類(Multimap等),Cache支援,等等。在Java8之前,Guava和Java之間的關係,可以表示成下面這幅圖: 但是隨著Ja

Swift學習筆記5:集合類型

nbsp roc 三種 一個 刪除指定元素 edge 空值 port 自定義 目錄: 數組:Array 集合:Set 字典:Dictionary Swift提供Array(有序集合數據)、Set(無序無重復集合)和Dictionary(無序鍵值對集合)三

bootstrap 學習筆記5---- 圖片和響應式工具

-h thumb ima ble resp 圓角 rim ucc spl (一)響應式圖片: 在 Bootstrap 版本 3 中,通過為圖片添加 .img-responsive 類可以讓圖片支持響應式布局。其實質是為圖片設置了 max-width: 100%;、 heig

學習筆記5---數學運算

mat tla fix bsp matlab 循環 支持 -- oot 一.開n次方 比如-8的立方根,用nthroot(-8,-3),不建議用(-8)^(1/3) 二. 乘除 向0取整數:clear all;clc;fix(7/2)ans = 3-----------

QT學習筆記5 菜單欄、工具欄、窗口、對話框

let qlabel rman 運行 內存空間 介紹 edi left setw 本程序主要介紹了以下幾種常用控件的使用方法: (1)菜單欄、工具欄 (2)核心控件、狀態欄、浮動窗口 (3)模態窗口、非模態窗口 (4)標準對話框、文件對話框 代碼如下: mainwindow

Hibernate學習筆記5---Query接口

center 結束 mce factory rst lis 聚集 數據庫 ber Hibernate中具有三種檢索方式(HQL,QBC,SQL) Query接口 一個查詢接口,用於向數據庫中查詢對象。並控制執行查詢的過程。Query接口內封裝了一個HQL查詢語句。 舉個栗子

JAVA8學習筆記----三個預定義接口

筆記 mps pub cti set nal () ack temp 三個函數接口概述JDK預定義了很多函數接口以避免用戶重復定義。最典型的是Function:@FunctionalInterface public interface Function<T, R>

Java8學習筆記--Stream API詳解[轉]

有效 編程效率 實時處理 phaser 綜合 files -- bin 並發模式 為什麽要使用StreamStream 作為 Java 8 的一大亮點,它與 java.io 包裏的 InputStream 和 OutputStream 是完全不同的概念。它也不同於 StAX

SpringBoot學習筆記5:處理前端JSON返回的日期的格式

處理 date() ring row 學習筆記 post 直觀 val rtt SpringBoot學習筆記(4):處理前端JSON返回的日期的格式 問題描述   前端頁面顯示的時間為毫秒格式,不利於直觀顯示! 解決方法1——後端解決 public class Flow

ojective-C學習筆記5關於面向對象編程

reat com new 面向對象 cti 重要 dispatch circle 術語 先了解幾個OC中有關面向對象編程的術語 類(class)是一種表示對象類型的結構體。這裏所說的結構體和C語言中的結構體不是一回事。 對象(object)是一種包含值和指向其類的隱藏指針的

yii學習筆記5,視圖操作

this 添加 func 創建 fun brush 視圖 urn AS 在控制器調用$this->render()方法來輸出視圖 function actionLogin(){ $name = "admin";    // 加載視圖 return $

Docker學習筆記-5容器數據管理,鏈接容器,構建私有庫

控制 st2 容器數據 pan 備份文件 data- 否則 所有 連接 五、容器數據管理,鏈接容器,構建私有庫 ① 容器數據管理 docker管理數據的方式有兩種: 數據卷 數據卷容器 1. 數據卷 數據卷是一個或多個容器專門指定繞過Union File System的

STM32學習筆記5——通用定時器PWM輸出

part 大小 模式 lan 晶振 kcon 筆記 利用 .cn 1、TIMER輸出PWM基本概念 脈沖寬度調制(PWM),是英文“Pulse Width Modulation”的縮寫,簡稱脈寬調制,是利用微處理器的數字輸出來對模擬

Rust語言學習筆記5

完全 ack 結構 some not eight bject pixel ring Structs(結構體) struct User { username: String, email: String, sign_in_count: u64,

TCP/IP學習筆記5------IP選路

use 網絡通 icmp報文 子網掩碼 出現 很好 ref 命令 時間間隔 靜態IP選路 一個簡單的路由表 選路是IP層最重要的一個功能之一。前面的部分已經簡單的講過路由器是通過何種規則來根據IP數據包的IP地址來選擇路由。這裏就不重復了。首先來看看一個簡單的系統路由表。

C語言學習筆記5—— 語句1

  c程式常見結構大概有選擇結構,迴圈結構,順序結構。c程式由一個一個的函式構成,而構成函式的則是語句,語句包含賦值語句,迴圈語句,條件語句,分支語句。賦值語句對與我們來說是很熟悉的。條件語句,分支語句與迴圈語句則會在後面一一介紹到。   順序結構對於我們來說是很熟悉的,它可以是這個樣子。 &nbs

C語言學習筆記5—— 語句2

  在介紹過順序結構和選擇結構以後,我們能通過c語言做的事依舊很少,比如換硬幣問題。將一元的人民幣換成一分,兩分,五分的硬幣共50枚。如何解決這樣的問題呢?我們可以把它化解成一個求解線性方程組的問題。   可以設需要一分的硬幣x枚,兩分的硬幣y枚,五分的硬幣z枚。於是,我們可以得到一個方程組,像這樣:x+y

cesium 學習筆記52018.11.08

1.預設檢視設定: viewer.zoomTo(viewer.entities); 2.繪製形狀 立方體:box ;點:point ; 橢圓ellipse; 3.繪製橢圓柱體發現的問題: 第一個position的高度為水平高度,semiMinorAxis等為長短軸,height為

linux學習筆記5:檔案許可權

檔案許可權 1.檔案許可權存在的意義 系統最底層安全設定方法之一 保證檔案可以被可用的使用者做相應操作 2.檔案許可權的檢視 ls -l file ls -ld dir ll file ll -d dir 3.檔案許可權的讀取 - |rw-rw-r--|

RocketMQ學習筆記5----RocketMQ監控平臺rocketmq-console-ng的搭建

1. 下載rocketmq-console-ng   官網地址:https://github.com/apache/rocketmq-externals      拉下來之後,使用idea開啟rocketmq-console,在application.properties配置檔案中修改rocketmq.