guava vs jdk8 原

#Guava Guava是Google公司開源的一個實用工具庫,對Java類庫進行了多方面的增強。比如說,對函數式編程的支持,新的集合類(Multimap等),Cache支持,等等。在Java8之前,Guava和Java之間的關係,可以表示成下面這幅圖: 但是隨着Java8的發佈,Guava和Java的關係發生了一些改變。Guava提供的很多功能,被內置在了Java8裏,如下圖所示:

源碼: Github Google Code API: API Users' Guide:Users' Guide

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

    • 使用guava
    public static String useGuava(List strList) {
        return Joiner.on(",").skipNulls().join(strList);
    }
    
    • 使用jdk8
    public static String useJdk8(List strList) {
        //lambda表達式
        return strList.stream().filter(m -> m != null).collect(Collectors.joining(","));
    }
    
    • 使用jdk7以及jdk7之前的版本
    public static String useJdk7(List strList) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < strList.size(); i++) {
            sb.append(strList.get(i));
            if (i + 1 != strList.size()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }
    
  2. Guava提供了Ordering類以方便我們創建Comparator

    • 使用guava
    public static List useGuava(List players) {
        Ordering ordering = Ordering.natural().nullsFirst().onResultOf(new Function() {
            @Override
            public Integer apply(Player foo) {
                return foo.getOrder();
            }
        });
    
        return ordering.sortedCopy(players);
    }
    
    • 使用jdk8
    public static List useJdk8(List players) {
        Comparator cmp = Comparator.comparing(Player::getOrder, Comparator.nullsFirst(Comparator.naturalOrder()));
    
        players.sort(cmp);
        return players;
    }
    
    • 使用jdk7以及jdk7之前的版本
    public static List useJdk7(List players) {
        players.sort(new Comparator() {
            @Override
            public int compare(Player o1, Player o2) {
                Integer order1 = o1.getOrder();
                Integer order2 = o2.getOrder();
    
                if (order1 > order2) {
                    return 1;
                } else if (order1 == order2) {
                    return 0;
                } else {
                    return -1;
                }
            }
        });
    
        return players;
    }
    
  3. 對null的處理

    • guava中對null的處理Optional

      • null是模棱兩可的,會引起令人困惑的錯誤,有些時候它讓人很不舒服。很多Guava工具類用快速失敗拒絕null值,而不是盲目地接受。
      • Optional是一個abstract類,兩個實現類PresentAbsent
        • Present: Implementation of an Optional containing a reference.
        • Absent: Implementation of an Optional not containing a reference.

      eg:

      // 創建一個非空對象,類型爲integer
      Optional possible = Optional.of(6);
      // Returns true if this holder contains a (non-null) instance.
      System.out.println("possible isPresent: " + possible.isPresent());
      System.out.println("possible value: " + possible.get());
      
      // 創建一個空對象
      Optional absentOpt = Optional.absent();
      // 取值,會報錯
      System.out.println("absentOpt value: " + absentOpt.get());
      
      // If nullableReference is non-null, returns an Optional instance containing that reference; otherwise returns Optional.absent.
      // fromNullable表示如果創建一個非空對象,則返回Present
      Optional<Integer> NoNullableOpt  = Optional.fromNullable(10);
      // 創建空對象,則返回Absent
      Optional<Integer> NullableOpt = Optional.fromNullable(null);
      

      其他詳細請查閱API - Guava Optional API

    • Guava使用Preconditions對null的預先判斷

      • 類似我們使用StringUtils等工具類
      • 但是不同的是,StringUtils等工具類是判斷是否爲空並得到結果,而Guava是使用判斷的結果,如果爲空,則直接拋異常。 eg.
      // givenName是傳入的參數
      String name = Preconditions.checkNotNull(givenName);
      // com.google.common.base.Preconditions.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) 
      
      // 而jdk8中的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
      
    • jdk8對null的處理 jdk8新加入類java.util.Optional,使用方法與Guava相似。關於jdk8中的Optional可參考遲到的Optional。Optional 被定義爲一個簡單的容器,其值可能是null或者不是null。在Java 8之前一般某個函數應該返回非空對象但是偶爾卻可能返回了null,而在Java 8中,不推薦你返回null而是返回Optional。 eg.

    // 不直接返回需要的類型String,而是返回Optional包含的String
    Optional<String> optional = Optional.of("bam");
    //  true if there is a value present, otherwise false
    optional.isPresent();           // true
    //  取值,如果爲空,則拋出異常NoSuchElementException
    optional.get();                 // "bam"
    // 如果爲空則返回傳入的值,否則返回其值
    optional.orElse("fallback");    // "bam"
    // 結合lambda表達式
    optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "b"
    

    其他詳細請查閱API - JDK8 Optional API

  4. 對於集合的處理

    • 創建集合
      • 普通做法 eg.

        List<Player> players = new ArrayList<Player>();
        players.add(new Player("bowen",20)); 
        players.add(new Player("bob", 20)); 
        players.add(new Player("Katy", 18)); 
        players.add(new Player("Logon", 24));
        
      • 在Guava中: eg.

        List<Player>  players = Lists.newArrayList(new Player("bowen", 20), new Player("bob", 20), new Player("Katy", 18), new Player("Logon", 24));
        
      • Java中: eg.

        List<Player> players = new ArrayList<Player>() { {
            add(new Player("bowen", 20));
            add(new Player("bob", 20));
            add(new Player("Katy", 18));
            add(new Player("Logon", 24));
        

}}; - 操作集合 要求:按年齡將上述人員分組 - 通常的做法(jdk8之前的版本)java public void mapListJava7(List<Player> players) { Map<Integer, List<Player>> groups = new HashMap<>(); for (Player player : players) { List<Player> group = groups.get(player.getAge()); if (group == null) { group = new ArrayList<>(); groups.put(player.getAge(), group); } group.add(player); } } - 在guava中,提供了`Multimap `java public void guavaMultimap(List<Player> players) {
Multimap<Integer, Player> groups = ArrayListMultimap.create();
for (Player player : players) {
groups.put(player.getAge(), player);
}
} - 在jdk8中,給Map添加了一個新的方法`getOrDefault()`,即使不用lambda表達式,代碼也清潔許多:java // 非lambda public void mapListJava8(List<Player> players) {
Map<Integer, List<Player>> groups = new HashMap<>();
for (Player player : players) {
List<Player> group = groups.getOrDefault(player.getAge(), new ArrayList<>());
group.add(player); groups.put(player.getAge(), group); }
}

    // 使用lambda表達式
    public void groupingByJava8(List<Player> players) {  
        Map<Integer, List<Player>> groups = players.stream().collect(Collectors.groupingBy(Player::getAge));  
    }  
    ```
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章