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"
複製程式碼