Java8新特性

1.避免空指針異常-Optional 類

空指針異常是我們日常項目中經常出現的問題,一般在操作前必須進行判空處理,Java8中引入了 Optional 類可以幫助我們避免顯式判空處理。

  1. Optional.of(T value),該方法通過一個非 null 的 value 來構造一個 Optional,返回的 Optional 包含了 value 這個值。對於該方法,傳入的參數一定不能爲 null,否則便會拋出 NullPointerException。
  2. Optional.ofNullable(T value),該方法和 of 方法的區別在於,傳入的參數可以爲 null

2.時間工具類-LocalDateTime

LocalDateTime是用於處理日期和時間的新API,比之前使用Date和Calendar更加方便。

// 取當前日期:
LocalDate today = LocalDate.now(); // -> 2014-12-24
// 根據年月日取日期:
LocalDate crischristmas = LocalDate.of(2014, 12, 25); // -> 2014-12-25
// 根據字符串取:
LocalDate endOfFeb = LocalDate.parse("2014-02-28"); // 嚴格按照ISO yyyy-MM-dd驗證,02寫成2都不行,當然也有一個重載方法允許自己定義格式
LocalDate.parse("2014-02-29"); // 無效日期無法通過:DateTimeParseException: Invalid date
// 取本月第1天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2017-03-01
// 取本月第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2017-03-02
// 取本月最後一天,再也不用計算是28,29,30還是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2017-12-31
// 取下一天:
LocalDate firstDayOf2015 = lastDayOfThisMonth.plusDays(1); // 變成了2018-01-01
// 取2017年1月第一個週一,用Calendar要死掉很多腦細胞:
LocalDate firstMondayOf2015 = LocalDate.parse("2017-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2017-01-02

3.流式處理-Stream

Stream是 Java 8新增加的類,用來補充集合類。Stream代表數據流,流中的數據元素的數量可能是有限的,也可能是無限的。

Stream提供了提供了串行和並行兩種類型的流,保持一致的接口,提供函數式編程方式,以管道方式提供中間操作和最終執行操作,爲Java語言的集合提供了現代語言提供的類似的高階函數操作,簡化和提高了Java集合的功能。

參考鏈接 Stream流處理

4.lambda表達式

那麼在Java8之前,可以藉助匿名內部類來實現一個List<String>按字符串長度進行排序,使用Lambda表達式來實現可以只需要更簡單的代碼。

List<String> words = Arrays.asList("apple", "banana", "pear");

//java8之前的內部類方法
words.sort(new Comparator<String>() {
 
    @Override
    public int compare(String w1, String w2) {
        return Integer.compare(w1.length(), w2.length());
    }
 
});

//lambda表達式
words.sort((String w1, String w2) -> {
    return Integer.compare(w1.length(), w2.length());
});

5.函數式接口

lambda表達式可以更好的完成函數式接口。創建包含單一抽象方法的接口,併爲其添加@FunctionalInterface註解,這類接口稱爲函數式接口。該註解不是必須的,通常需要加上,會觸發編譯器編譯時校驗接口是否符合要求,通常該接口只包含一個抽象方法,但是可以定義object的toStringequals方法。

/**
 * 函數式接口
 * @param <T>
 */
@FunctionalInterface
interface Checker<T extends String>{
    boolean check(T t);
}

@FunctionalInterface
interface Out<T>{
    void achievement(T t);
}

public class FunctionalInterfaceTest {

    @Test
    public void testLambda() {
        List<String> demoList = Arrays.asList("小明", "Zing", "阿三", "小紅", "趙日天");
        rollCall(demoList,
                name-> name.startsWith("Z"),
                name->{
                    String rate = name + "是單身狗!";
                    System.out.println(rate);
                });
    }

    public void rollCall(List<? extends String> list, Checker checker,Out out){
        for(String name : list){
            if(checker.check(name)){
                out.achievement(name);
            }
        }
    }
}

6.方法引用

方法引用是一種語法糖,編譯器會將其轉換成函數式接口的實現對象,存在三種方法引用:引用方法、引用構造器、引用數組。這些方法主要是引用 java.util.function包中方法,可以參考JAVA 8 函數式接口( java.util.function 詳解)

//引用方法

// Consumer<String> consumer = x -> System.out.println(x);
// println對應抽象方法的具體實現
Consumer<String> consumer = System.out::println;  
consumer.accept("This is Major Tom");

// Function<Long, Long> f = x -> Math.abs(x);
// abs對應抽象方法的具體實現
Function<Long, Long> f = Math::abs;  
System.out.println(f.apply(-3L));

// BiPredicate<String, String> b = (x,y) -> x.equals(y);
BiPredicate<String, String> b = String::equals;
System.out.println(b.test("abc", "abcd"));

//引用構造器
// Function<Integer, StringBuffer> fun = n -> new StringBuffer(n);
Function<Integer, StringBuffer> fun = StringBuffer::new;
StringBuffer buffer = fun.apply(10);

//引用數組
// Function<Integer, int[]> fun = n -> new int[n];
Function<Integer, int[]> fun = int[]::new;
int[] arr = fun.apply(10);

 

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