JAVA8 新特性實際使用總結(一)

弱冠季首發表於2018-02-08

Optional

public final class Optional extends Object

A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

容器物件,可能包含或不包含非空值。如果存在一個值,isPresent()將返回true並 get()返回值。

Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).

還提供了依賴於包含值是否存在的其他方法,例如orElse() (如果值不存在,則返回一個預設值)以及ifPresent()(如果值存在,則 執行一個程式碼塊)。

This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Optional may have unpredictable results and should be avoided.

這是一個基於值的類; 應該慎用相等操作(包括==,hahcode 或 synchronization) Optional可能會產生不可預知的結果,應予以避免。


個人理解 Optional實際上是個容器:它可以儲存型別T的值,或者僅僅儲存null。Optional提供很多有用的方法,這樣我們就不用顯式進行空值檢測。


常規用法

 Integer a = null;
        
//賦值
//a=null  所以丟擲 NullPointerException 
Optional<Integer> optional=Optional.of(a);
// 不會丟擲異常
Optional<Integer> optional = Optional.ofNullable(a);

//判空
//isNotNull=false
boolean isNotNull = optional.isPresent();

//取值
//a=null 所以丟擲NoSuchElementException 否則value=a
Integer value=optional.get();
//a=null 所以value=0 否則value=a
Integer value = optional.orElse(0);

//a=null 所以不會列印 否則 列印a的值
optional.ifPresent(System.out::println);

//a=null 所以b=0 否則b=1
int b=optional.map((v)-> v++).orElse(0);
複製程式碼

具體說明of

public static <T> Optional<T> of(T value)
複製程式碼

根據value返回一個Optional。當value為null時會報空指標異常。引數不能為空

ofNullable

public static <T> Optional<T> ofNullable(T value)
複製程式碼

根據value返回一個Optional,如果引數為null,返回一個空的Optional。引數可以為空

get

public T get()
複製程式碼

當值存在則返回值,否則(值為null)丟擲NoSuchElementException異常

orElse

public T orElse(T other)
複製程式碼

當值存在則返回值,否則(值為null)返回other的值。 orElse()方法和orElseGet()方法類似,但是orElse接受一個預設值而不是一個回撥函式

isPresent

public boolean isPresent()
複製程式碼

當值存在則返回true否則返回false,判空用

ifPresent

public void ifPresent(Consumer<? super T> consumer)
複製程式碼

如果存在值,則使用該值呼叫回撥函式

注意: 雖然 iPresent 函式可以當值不為空時執行回撥函式,但是隻能針對當前值,且無返回值。比如你想值不為null時進行加減b變數,則應該使用map方法進行操作。

其他實用通用的方法:

先宣告一個集合後面使用:

List<String> stringCollection = new ArrayList<>();
stringCollection.add("ddd2");
stringCollection.add("aaa2");
stringCollection.add("bbb1");
stringCollection.add("aaa1");
stringCollection.add("bbb3");
stringCollection.add("ccc");
stringCollection.add("bbb2");
stringCollection.add("ddd1");
複製程式碼

Filter 過濾

過濾通過一個predicate介面來過濾並只保留符合條件的元素,該操作屬於中間操作,所以我們可以在過濾後的結果來應用其他Stream操作(比如forEach)。forEach需要一個函式來對過濾後的元素依次執行。forEach是一個最終操作,所以我們不能在forEach之後來執行其他Stream操作。

stringCollection
    .stream()
    .filter((s) -> s.startsWith("a"))
    .forEach(System.out::println);
    // "aaa2", "aaa1"
複製程式碼

Sort 排序

排序是一箇中間操作,返回的是排序好後的Stream。如果你不指定一個自定義的Comparator則會使用預設排序。 複製程式碼 程式碼如下:

stringCollection
    .stream()
    .sorted()
    .filter((s) -> s.startsWith("a"))
    .forEach(System.out::println);
    // "aaa1", "aaa2"
複製程式碼

需要注意的是,排序只建立了一個排列好後的Stream,而不會影響原有的資料來源,排序之後原資料stringCollection是不會被修改的:

System.out.println(stringCollection);
//ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1
複製程式碼

Map 對映

中間操作map會將元素根據指定的Function介面來依次將元素轉成另外的物件,下面的示例展示了將字串轉換為大寫字串。你也可以通過map來講物件轉換成其他型別,map返回的Stream型別是根據你map傳遞進去的函式的返回值決定的。

stringCollection
    .stream()
    .map(String::toUpperCase)
    .sorted((a, b) -> b.compareTo(a))
    .forEach(System.out::println);
// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"
複製程式碼

Match 匹配

Stream提供了多種匹配操作,允許檢測指定的Predicate是否匹配整個Stream。所有的匹配操作都是最終操作,並返回一個boolean型別的值。

boolean anyStartsWithA = 
    stringCollection
        .stream()
        .anyMatch((s) -> s.startsWith("a"));
System.out.println(anyStartsWithA);      // true
boolean allStartsWithA = 
    stringCollection
        .stream()
        .allMatch((s) -> s.startsWith("a"));
System.out.println(allStartsWithA);      // false
boolean noneStartsWithZ = 
    stringCollection
        .stream()
        .noneMatch((s) -> s.startsWith("z"));
System.out.println(noneStartsWithZ);      // true
複製程式碼

Count 計數

計數是一個最終操作,返回Stream中元素的個數,返回值型別是long。 複製程式碼 程式碼如下:

long startsWithB = 
    stringCollection
        .stream()
        .filter((s) -> s.startsWith("b"))
        .count();
System.out.println(startsWithB);    // 3
複製程式碼

Reduce 規約

這是一個最終操作,允許通過指定的函式來講stream中的多個元素規約為一個元素,規越後的結果是通過Optional介面表示的:

Optional<String> reduced =
    stringCollection
        .stream()
        .sorted()
        .reduce((s1, s2) -> s1 + "#" + s2);
reduced.ifPresent(System.out::println);
// "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"
複製程式碼

Optional JSE文件

相關文章