Java 8 Optionalæä½³æåï¼ä¼é è§£å³ç©ºæé
æ³å¦ä¹ ï¼æ°¸è¿é½ä¸æï¼å°¤å ¶æ¯é对 Java 8 éé¢ç好ä¸è¥¿ï¼Optional å°±æ¯å ¶ä¸ä¹ä¸ï¼è¯¥ç±»æä¾äºä¸ç§ç¨äºè¡¨ç¤ºå¯éå¼èé空å¼ç¨ç类级å«è§£å³æ¹æ¡ãä½ä¸ºä¸å Java ç¨åºåï¼æççæ¯ç¦éäº NullPointerExceptionï¼NPEï¼ï¼å°½ç®¡åå®çå¾å°±åä¸ä½èæåï¼ç¥éå®ä¹æ¯è¿«ä¸å¾å·²ââç¨åºæ£å¨ä½¿ç¨ä¸ä¸ªå¯¹è±¡å´åç°è¿ä¸ªå¯¹è±¡çå¼ä¸º nullï¼äºæ¯ Java èææºå°±æåå²å 尿宿äºåºæ¥å½åæ¿ç½ªç¾ã
å½ç¶äºï¼æä»¬ç¨åºåæ¯å¯æè´£ä»»å¿çï¼ä¸ä¼åè§ä¸ç®¡ï¼äºæ¯å°±æäºå¤§éç null 弿£æ¥ãå°½ç®¡ææ¶åè¿ç§æ£æ¥å®å ¨æ²¡æå¿ è¦ï¼ä½æä»¬å·²ç»ä¹ æ¯äºä¾è¡å ¬äºãç»äºï¼Java 8 çä¸ä¸å»äºï¼å°±å¼å ¥äº Optionalï¼ä»¥ä¾¿æä»¬ç¼åç代ç ä¸åé£ä¹å»èåæ¿ã

01ãæ²¡æ Optional 伿ä»ä¹é®é¢
æä»¬æ¥æ¨¡æä¸ä¸ªå®é çåºç¨åºæ¯ãå°ç第ä¸å¤©ä¸çï¼é¢å¯¼è马就ç»ä»å®æäºä¸ä¸ªä»»å¡ï¼è¦ä»ä»æ°æ®åºä¸æ ¹æ®ä¼å ID æåä¸ä¸ªä¼åçå§åï¼ç¶åå°å§åæå°å°æ§å¶å°ãè½ç¶æ¯æ°æ¥çï¼ä½è¿ä¸ªä»»å¡é¾ä¸åå°çï¼äºæ¯ä»è±äº 10 åéåä¸äºè¿æ®µä»£ç ï¼
public class WithoutOptionalDemo {
class Member {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Member mem = getMemberByIdFromDB();
if (mem != null) {
System.out.println(mem.getName());
}
}
public static Member getMemberByIdFromDB() {
// å½å ID çä¼åä¸åå¨
return null;
}
}ç±äºå½å ID çä¼åä¸åå¨ï¼æä»¥ getMemberByIdFromDB() æ¹æ³è¿åäº null æ¥ä½ä¸ºæ²¡æè·åå°è¯¥ä¼åçç»æï¼é£å°±æå³ç卿å°ä¼åå§åçæ¶åè¦å
对 mem å¤ç©ºï¼å¦åå°±ä¼æåº NPE å¼å¸¸ï¼ä¸ä¿¡ï¼è®©å°çæ if (mem != null) 廿è¯è¯ï¼æ§å¶å°ç«é©¬æå°éè¯¯å æ ç»ä½ é¢è²ççã
Exception in thread "main" java.lang.NullPointerException
at com.cmower.dzone.optional.WithoutOptionalDemo.main(WithoutOptionalDemo.java:24)02ãOptional æ¯å¦ä½è§£å³è¿ä¸ªé®é¢ç
å°çæä»£ç æäº¤åï¼å°±å ´é«éçå°å»æ¾èé©¬è¦æ°çä»»å¡äºãæ¬çèå¿å¦ä¹ çæåº¦ï¼å°ç请æ±è马çä¸ä¸èªå·±ç代ç ï¼äºæ¯èçå°±åè¯ä»åºè¯¥å°è¯ä¸ä¸ Optionalï¼å¯ä»¥é¿å 没æå¿ è¦ç null 弿£æ¥ãç°å¨ï¼è®©æä»¬æ¥ççå°çæ¯å¦ä½éè¿ Optional æ¥è§£å³ä¸è¿°é®é¢çã
public class OptionalDemo {
public static void main(String[] args) {
Optional<Member> optional = getMemberByIdFromDB();
optional.ifPresent(mem -> {
System.out.println("ä¼åå§åæ¯ï¼" + mem.getName());
});
}
public static Optional<Member> getMemberByIdFromDB() {
boolean hasName = true;
if (hasName) {
return Optional.of(new Member("æ²é»çäº"));
}
return Optional.empty();
}
}
class Member {
private String name;
public String getName() {
return name;
}
// getter / setter
}getMemberByIdFromDB() æ¹æ³è¿åäº Optional<Member> ä½ä¸ºç»æï¼è¿æ ·å°±è¡¨æ Member å¯è½åå¨ï¼ä¹å¯è½ä¸åå¨ï¼è¿æ¶åå°±å¯ä»¥å¨ Optional ç ifPresent() æ¹æ³ä¸ä½¿ç¨ Lambda è¡¨è¾¾å¼æ¥ç´æ¥æå°ç»æã
Optional 乿以å¯ä»¥è§£å³ NPE çé®é¢ï¼æ¯å ä¸ºå®æç¡®çåè¯æä»¬ï¼ä¸éè¦å¯¹å®è¿è¡å¤ç©ºãå®å°±å¥½åååè·¯å£çè·¯æ ï¼æç¡®å°åè¯ä½ 该å¾åªèµ°ã
03ãå建 Optional 对象
1ï¼å¯ä»¥ä½¿ç¨éææ¹æ³ empty() å建ä¸ä¸ªç©ºç Optional 对象
Optional<String> empty = Optional.empty();
System.out.println(empty); // è¾åºï¼Optional.empty2ï¼å¯ä»¥ä½¿ç¨éææ¹æ³ of() å建ä¸ä¸ªé空ç Optional 对象
Optional<String> opt = Optional.of("æ²é»çäº");
System.out.println(opt); // è¾åºï¼Optional[æ²é»çäº]å½ç¶äºï¼ä¼ éç» of() æ¹æ³çåæ°å¿
é¡»æ¯é空çï¼ä¹å°±æ¯è¯´ä¸è½ä¸º nullï¼å¦åä»ç¶ä¼æåº NullPointerExceptionã
String name = null;
Optional<String> optnull = Optional.of(name);3ï¼å¯ä»¥ä½¿ç¨éææ¹æ³ ofNullable() å建ä¸ä¸ªå³å¯ç©ºåå¯é空ç Optional 对象
String name = null;
Optional<String> optOrNull = Optional.ofNullable(name);
System.out.println(optOrNull); // è¾åºï¼Optional.emptyofNullable() æ¹æ³å
鍿ä¸ä¸ªä¸å
表达å¼ï¼å¦æä¸ºåæ°ä¸º nullï¼åè¿åç§æå¸¸é EMPTYï¼å¦åä½¿ç¨ new å
³é®åå建äºä¸ä¸ªæ°ç Optional 对象ââä¸ä¼åæåº NPE å¼å¸¸äºã
04ã夿弿¯å¦åå¨
å¯ä»¥éè¿æ¹æ³ isPresent() 夿ä¸ä¸ª Optional 对象æ¯å¦åå¨ï¼å¦æåå¨ï¼è¯¥æ¹æ³è¿å trueï¼å¦åè¿å falseââåä»£äº obj != null ç夿ã
Optional<String> opt = Optional.of("æ²é»çäº");
System.out.println(opt.isPresent()); // è¾åºï¼true
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(optOrNull.isPresent()); // è¾åºï¼falseJava 11 åè¿å¯ä»¥éè¿æ¹æ³ isEmpty() å¤æä¸ isPresent() ç¸åçç»æã
Optional<String> opt = Optional.of("æ²é»çäº");
System.out.println(opt.isEmpty()); // è¾åºï¼false
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(optOrNull.isEmpty()); // è¾åºï¼true05ãé空表达å¼
Optional ç±»æä¸ä¸ªé常ç°ä»£åçæ¹æ³ââifPresent()ï¼å
许æä»¬ä½¿ç¨å½æ°å¼ç¼ç¨çæ¹å¼æ§è¡ä¸äºä»£ç ï¼å æ¤ï¼ææå®ç§°ä¸ºé空表达å¼ãå¦ææ²¡æè¯¥æ¹æ³çè¯ï¼æä»¬é常éè¦å
éè¿ isPresent() æ¹æ³å¯¹ Optional 对象è¿è¡å¤ç©ºååæ§è¡ç¸åºç代ç ï¼
Optional<String> optOrNull = Optional.ofNullable(null);
if (optOrNull.isPresent()) {
System.out.println(optOrNull.get().length());
}æäº ifPresent() ä¹åï¼æ
åµå°±å®å
¨ä¸åäºï¼å¯ä»¥ç´æ¥å° Lambda 表达å¼ä¼ éç»è¯¥æ¹æ³ï¼ä»£ç æ´å ç®æ´ï¼æ´å ç´è§ã
Optional<String> opt = Optional.of("æ²é»çäº");
opt.ifPresent(str -> System.out.println(str.length()));Java 9 åè¿å¯ä»¥éè¿æ¹æ³ ifPresentOrElse(action, emptyAction) æ§è¡ä¸¤ç§ç»æï¼éç©ºæ¶æ§è¡ actionï¼ç©ºæ¶æ§è¡ emptyActionã
Optional<String> opt = Optional.of("æ²é»çäº");
opt.ifPresentOrElse(str -> System.out.println(str.length()), () -> System.out.println("为空"));06ã设置ï¼è·åï¼é»è®¤å¼
ææ¶åï¼æä»¬å¨å建ï¼è·åï¼ Optional å¯¹è±¡çæ¶åï¼éè¦ä¸ä¸ªé»è®¤å¼ï¼orElse() å orElseGet() æ¹æ³å°±æ´¾ä¸ç¨åºäºã
orElse() æ¹æ³ç¨äºè¿åå
è£¹å¨ Optional 对象ä¸çå¼ï¼å¦æè¯¥å¼ä¸ä¸º nullï¼åè¿åï¼å¦åè¿åé»è®¤å¼ãè¯¥æ¹æ³çåæ°ç±»ååå¼çç±»åä¸è´ã
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("æ²é»çäº");
System.out.println(name); // è¾åºï¼æ²é»çäºorElseGet() æ¹æ³ä¸ orElse() æ¹æ³ç±»ä¼¼ï¼ä½åæ°ç±»åä¸åã妿 Optional 对象ä¸çå¼ä¸º nullï¼åæ§è¡åæ°ä¸ç彿°ã
String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(()->"æ²é»çäº");
System.out.println(name); // è¾åºï¼æ²é»çäºä»è¾åºç»æä»¥å代ç çå½¢å¼ä¸æ¥çï¼è¿ä¸¤ä¸ªæ¹æ³æå ¶ç¸ä¼¼ï¼è¿ä¸å å¼èµ·æä»¬çæçï¼Java ç±»åºçè®¾è®¡è æå¿ è¦è¿æ ·ååï¼
å设ç°å¨æè¿æ ·ä¸ä¸ªè·åé»è®¤å¼çæ¹æ³ï¼å¾ä¼ ç»çæ¹å¼ã
public static String getDefaultValue() {
System.out.println("getDefaultValue");
return "æ²é»çäº";
}ç¶åï¼éè¿ orElse() æ¹æ³å orElseGet() æ¹æ³åå«è°ç¨ getDefaultValue() æ¹æ³è¿åé»è®¤å¼ã
public static void main(String[] args) {
String name = null;
System.out.println("orElse");
String name2 = Optional.ofNullable(name).orElse(getDefaultValue());
System.out.println("orElseGet");
String name3 = Optional.ofNullable(name).orElseGet(OrElseOptionalDemo::getDefaultValue);
}注ï¼ç±»å :: æ¹æ³åæ¯ Java 8 å¼å
¥çè¯æ³ï¼æ¹æ³åå颿¯æ²¡æ () çï¼è¡¨æè¯¥æ¹æ³å¹¶ä¸ä¸å®ä¼è¢«è°ç¨ã
è¾åºç»æå¦ä¸æç¤ºï¼
orElse
getDefaultValue
orElseGet
getDefaultValueè¾åºç»ææ¯ç¸ä¼¼çï¼æ²¡ä»ä¹å¤ªå¤§çä¸åï¼è¿æ¯å¨ Optional 对象çå¼ä¸º null çæ åµä¸ãåå¦ Optional 对象çå¼ä¸ä¸º null å¢ï¼
public static void main(String[] args) {
String name = "æ²é»çä¸";
System.out.println("orElse");
String name2 = Optional.ofNullable(name).orElse(getDefaultValue());
System.out.println("orElseGet");
String name3 = Optional.ofNullable(name).orElseGet(OrElseOptionalDemo::getDefaultValue);
}è¾åºç»æå¦ä¸æç¤ºï¼
orElse
getDefaultValue
orElseGetå¦ï¼orElseGet() 没æå»è°ç¨ getDefaultValue()ãåªä¸ªæ¹æ³çæ§è½æ´ä½³ï¼ä½ æç½äºå§ï¼
07ãè·åå¼
ç´è§ä»è¯ä¹ä¸æ¥çï¼get() æ¹æ³ææ¯ææ£å®çè·å Optional 对象å¼çæ¹æ³ï¼ä½å¾éæ¾ï¼è¯¥æ¹æ³æ¯æç¼ºé·çï¼å 为åå¦ Optional 对象çå¼ä¸º nullï¼è¯¥æ¹æ³ä¼æåº NoSuchElementException å¼å¸¸ãè¿å®å
¨ä¸æä»¬ä½¿ç¨ Optional ç±»çåè¡·ç¸æã
public class GetOptionalDemo {
public static void main(String[] args) {
String name = null;
Optional<String> optOrNull = Optional.ofNullable(name);
System.out.println(optOrNull.get());
}
}è¿æ®µç¨åºå¨è¿è¡æ¶ä¼æåºå¼å¸¸ï¼
Exception in thread "main" java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:141)
at com.cmower.dzone.optional.GetOptionalDemo.main(GetOptionalDemo.java:9)尽管æåºçå¼å¸¸æ¯ NoSuchElementException è䏿¯ NPEï¼ä½å¨æä»¬çæ¥ï¼æ¾ç¶æ¯å¨âäºåæ¥ç¬ç¾æ¥âã建议 orElseGet() æ¹æ³è·å Optional 对象çå¼ã
08ãè¿æ»¤å¼
å°çéè¿ Optional 类对ä¹åç代ç è¿è¡äºå级ï¼å®æååå ´é«éçå°è·å»æ¾è马è¦ä»»å¡äºãè马è§å¾è¿å°ä¼åä¸éï¼å¤´èçµæ´»ï¼å干活积æï¼å¾å¼å¾å¹å »ï¼å°±å交ç»äºå°çä¸ä¸ªæ°çä»»å¡ï¼ç¨æ·æ³¨åæ¶å¯¹å¯ç çé¿åº¦è¿è¡æ£æ¥ã
å°çæ¿å°ä»»å¡åï¼ä¹å¼äºè±ï¼å 为ä»åè¦å¦ä¹ Optional ç±»ç filter() æ¹æ³ï¼è¿å°±æ´¾ä¸äºç¨åºã
public class FilterOptionalDemo {
public static void main(String[] args) {
String password = "12345";
Optional<String> opt = Optional.ofNullable(password);
System.out.println(opt.filter(pwd -> pwd.length() > 6).isPresent());
}
}filter() æ¹æ³çåæ°ç±»å为 Predicateï¼Java 8 æ°å¢çä¸ä¸ªå½æ°å¼æ¥å£ï¼ï¼ä¹å°±æ¯è¯´å¯ä»¥å°ä¸ä¸ª Lambda 表达å¼ä¼ éç»è¯¥æ¹æ³ä½ä¸ºæ¡ä»¶ï¼å¦æè¡¨è¾¾å¼çç»æä¸º falseï¼åè¿åä¸ä¸ª EMPTY ç Optional 对象ï¼å¦åè¿åè¿æ»¤åç Optional 对象ã
å¨ä¸ä¾ä¸ï¼ç±äº password çé¿åº¦ä¸º 5 ï¼æä»¥ç¨åºè¾åºçç»æä¸º falseãå设å¯ç çé¿åº¦è¦æ±å¨ 6 å° 10 ä½ä¹é´ï¼é£ä¹è¿å¯ä»¥å追å ä¸ä¸ªæ¡ä»¶ãæ¥çå°çå¢å é¾åº¦åç代ç ã
Predicate<String> len6 = pwd -> pwd.length() > 6;
Predicate<String> len10 = pwd -> pwd.length() < 10;
password = "1234567";
opt = Optional.ofNullable(password);
boolean result = opt.filter(len6.and(len10)).isPresent();
System.out.println(result);è¿æ¬¡ç¨åºè¾åºçç»æä¸º trueï¼å 为å¯ç åæäº 7 ä½ï¼å¨ 6 å° 10 ä½ä¹é´ãæ³è±¡ä¸ä¸ï¼åå¦å°çä½¿ç¨ if-else æ¥å®æè¿ä¸ªä»»å¡ï¼ä»£ç 该æå¤åé¿ã
09ã转æ¢å¼
å°çæ£æ¥å®äºå¯ç çé¿åº¦ï¼ä»ç¶è§å¾ä¸å¤å°½å
´ï¼è§å¾è¦å¯¹å¯ç ç强度ä¹è¿è¡æ£æ¥ï¼æ¯å¦è¯´å¯ç ä¸è½æ¯âpasswordâï¼è¿æ ·çå¯ç 太弱äºãäºæ¯ä»åå¼å§ç ç©¶èµ·äº map() æ¹æ³ï¼è¯¥æ¹æ³å¯ä»¥æç
§ä¸å®çè§åå°åæ Optional 对象转æ¢ä¸ºä¸ä¸ªæ°ç Optional 对象ï¼åæç Optional 对象ä¸ä¼æ´æ¹ã
å æ¥çå°çåçä¸ä¸ªç®åçä¾åï¼
public class OptionalMapDemo {
public static void main(String[] args) {
String name = "æ²é»çäº";
Optional<String> nameOptional = Optional.of(name);
Optional<Integer> intOpt = nameOptional
.map(String::length);
System.out.println( intOpt.orElse(0));
}
}å¨ä¸é¢è¿ä¸ªä¾åä¸ï¼map() æ¹æ³çåæ° String::lengthï¼æå³çè¦ å°åæçå符串类åç Optional æç
§å符串é¿åº¦éæ°çæä¸ä¸ªæ°ç Optional 对象ï¼ç±»å为 Integerã
ææ¸
æ¥äº map() æ¹æ³çåºæ¬ç¨æ³åï¼å°çå³å®æ map() æ¹æ³ä¸ filter() æ¹æ³ç»åèµ·æ¥ç¨ï¼åè
ç¨äºå°å¯ç 转å为å°åï¼åè
ç¨äºå¤æé¿åº¦ä»¥åæ¯å¦æ¯âpasswordâã
public class OptionalMapFilterDemo {
public static void main(String[] args) {
String password = "password";
Optional<String> opt = Optional.ofNullable(password);
Predicate<String> len6 = pwd -> pwd.length() > 6;
Predicate<String> len10 = pwd -> pwd.length() < 10;
Predicate<String> eq = pwd -> pwd.equals("password");
boolean result = opt.map(String::toLowerCase).filter(len6.and(len10 ).and(eq)).isPresent();
System.out.println(result);
}
}
好äºï¼æäº²ç±çè¯»è æåï¼ä»¥ä¸å°±æ¯æ¬æçå ¨é¨å 容äºââå¯ä»¥è¯´æ¯å²ä¸æä½³ Optional æåäºï¼è½çå°è¿éç齿¯æä¼ç§çç¨åºåï¼äºå¥å¿ é¡»è¦ä¼¸åºå¤§ææä¸ºä½ ç¹ä¸ªèµã
GitHub 䏿 æ 10000+ ç弿ºç¥è¯åºãäºå¥ç Java è¿é¶ä¹è·¯ã第ä¸ç PDF ç»äºæ¥äºï¼å æ¬Javaåºç¡è¯æ³ãæ°ç»&å符串ãOOPãéåæ¡æ¶ãJava IOãå¼å¸¸å¤çãJava æ°ç¹æ§ãç½ç»ç¼ç¨ãNIOãå¹¶åç¼ç¨ãJVMççï¼å ±è®¡ 32 ä¸ä½åï¼500+å¼ æç»å¾ï¼å¯ä»¥è¯´æ¯éä¿ææãé£è¶£å¹½é»â¦â¦è¯¦æ æ³ï¼å¤ªèµäºï¼GitHub 䏿 æ 10000+ ç Java æç¨
å¾®ä¿¡æ æ²é»çäº ææ«æä¸æ¹äºç»´ç å ³æ³¨äºå¥çååå ¬ä¼å·æ²é»çäºï¼åå¤ 222 å³å¯å è´¹é¢åã

