姒傝堪锛歄ptional鏈€鏃╂槸Google鍏徃Guava涓殑姒傚康锛屼唬琛ㄧ殑鏄彲閫夊€笺€侽ptional绫讳粠Java8鐗堟湰寮€濮嬪姞鍏ヨ豹鍗庡椁愶紝涓昏涓轰簡瑙e喅绋嬪簭涓殑NPE闂锛屼粠鑰屼娇寰楁洿灏戠殑鏄惧紡鍒ょ┖锛岄槻姝唬鐮佹薄鏌擄紝鍙︿竴鏂归潰锛屼篃浣垮緱棰嗗煙妯″瀷涓墍闅愯棌鐨勭煡璇嗭紝寰椾互鏄惧紡浣撶幇鍦ㄤ唬鐮佷腑銆侽ptional绫讳綅浜巎ava.util鍖呬笅锛屽閾惧紡缂栫▼椋庢牸鏈変竴瀹氱殑鏀寔銆傚疄闄呬笂锛孫ptional鏇村儚鏄竴涓鍣紝鍏朵腑瀛樻斁鐨勬垚鍛樺彉閲忔槸涓€涓猅绫诲瀷鐨剉alue锛屽彲鍊煎彲锛屼娇鐢ㄧ殑鏄疻rapper妯″紡锛屽value鎿嶄綔杩涜浜嗗寘瑁呬笌璁捐銆傛湰鏂囧皢浠嶰ptional鎵€瑙e喅鐨勯棶棰樺紑濮嬶紝閫愬眰瑙e墫锛岀敱娴呭叆娣憋紝鏂囦腑浼氬嚭鐜癘ptioanl鏂规硶涔嬮棿鐨勫姣旓紝瀹炶返锛岃鐢ㄦ儏鍐靛垎鏋愶紝浼樼己鐐圭瓑銆備笌澶у涓€璧凤紝瀵硅繖椤笿ava8涓殑鏂扮壒鎬э紝杩涜鐞嗚В鍜屾繁鍏ャ€?/p>
鑷悕鏄憲鐨勭┖鎸囬拡寮傚父锛屾槸姣忎釜绋嬪簭鍛橀兘浼氶亣鍒扮殑涓€绉嶅父瑙佸紓甯革紝浠讳綍璁块棶瀵硅薄鐨勬柟娉曚笌灞炴€х殑璋冪敤锛岄兘鍙兘浼氬嚭鐜癙ointException锛屽鏋滆纭繚涓嶈Е鍙戝紓甯革紝鎴戜滑閫氬父闇€瑕佽繘琛屽璞$殑鍒ょ┖鎿嶄綔銆?br style="box-sizing: border-box;">涓句釜鏍楀瓙锛屾湁涓€涓汉锛圫hopper锛夎繘瓒呭競璐墿锛屽彲鑳戒細鐢ㄨ喘鐗╄溅锛圱rolley锛変篃鍙兘浼氱敤鍏跺畠鏂瑰紡锛岃喘鐗╄溅閲屽彲鑳戒細鏈変竴琚嬫牀瀛愶紙Chestnut锛夛紝涔熷彲鑳芥病鏈夈€備笁鑰呭畾涔夌殑浠g爜濡備笅锛?/p>
public class Shopper {
private Trolley trolley;
public Trolley getTrolley(){
return trolley;
}
}
public class Trolley {
private Chestnut chestnut;
public Chestnut getChestnut(){
return chestnut;
}
}
public class Chestnut {
private String name;
public String getName(){
return name;
}
}
杩欐椂鎯宠鑾峰緱璐墿杞︿腑鏍楀瓙鐨勫悕绉帮紝鍍忎笅闈㈣繖涔堝啓锛屽氨鍙兘浼氳鍒版垜浠殑鈥滆€佹湅鍙嬧€濓紙NPE锛?/p>
public String result(Shopper shopper){
return shopper.getTrolley().getChestnut().getName();
}
涓轰簡鑳介伩鍏嶅嚭鐜扮┖鎸囬拡寮傚父锛岄€氬父鐨勫啓娉曚細閫愬眰鍒ょ┖锛堝灞傚祵濂楁硶锛夛紝濡備笅
public String result(Shopper shopper) {
if (shopper != ) {
Trolley trolley = shopper.getTrolley();
if (trolley != ) {
Chestnut chestnut = trolley.getChestnut();
if (chestnut != ) {
return chestnut.getName();
}
}
}
return "鑾峰彇澶辫触杈?;
}
澶氬眰宓屽鐨勬柟娉曞湪瀵硅薄绾ц仈鍏崇郴姣旇緝娣辩殑鏃跺€欎細鐪嬬殑鐪艰姳缂贡鐨勶紝灏ゅ叾鏄偅涓€灞備竴灞傜殑鎷彿馃槖锛涘彟澶栧嚭閿欑殑鍘熷洜涔熷洜涓虹己涔忓搴斾俊鎭€岃妯$硦锛堜緥濡倀rolley涓虹┖鏃朵篃鍙繑鍥炰簡鏈€鍚庣殑鑾峰彇澶辫触銆傚綋鐒朵篃鍙互鍦ㄦ瘡涓€灞傚鍔爎eturn锛岀浉搴旂殑浠g爜鏈変細鍙樺緱寰堝啑闀匡級锛屾墍浠ユ鏃舵垜浠篃鍙互鐢ㄩ亣绌哄垯杩斿洖鐨勫崼璇彞杩涜鏀瑰啓銆?/p>
public String result(Shopper shopper) {
if (shopper == ) {
return "璐墿鑰呬笉瀛樺湪";
}
Trolley trolley = shopper.getTrolley();
if (trolley == ) {
return "璐墿杞︿笉瀛樺湪";
}
Chestnut chestnut = trolley.getChestnut();
if (chestnut == ) {
return "鏍楀瓙涓嶅瓨鍦?;
}
return chestnut.getName();
}
涓轰簡鍙栦竴涓悕瀛楄繘琛屼簡涓夋鏄剧ず鍒ょ┖鎿嶄綔锛岃繖鏍风殑浠g爜褰撶劧娌℃湁闂锛屼絾鏄紭绉€鐨勫伐绋嬪笀浠€绘槸甯屾湜鑳借幏寰楁洿浼橀泤绠€娲佺殑浠g爜銆侽ptional灏辨彁渚涗簡涓€浜涙柟娉曪紝瀹炵幇浜嗚繖鏍风殑鏈熸湜銆?/p>
public String result(Shopper shopper){
return Optional.ofable(shopper)
.map(Shopper::getTrolley)
.map(Trolley::getChestnut)
.map(Chestnut::getName)
.orElse("鑾峰彇澶辫触杈?);
}
Optional绫讳腑鏈変袱涓瀯閫犳柟娉曪細甯﹀弬鍜屼笉甯﹀弬鐨勩€傚甫鍙傜殑灏嗕紶鍏ョ殑鍙傛暟璧嬪€紇alue锛屼粠鑰屾瀯寤篛ptional瀵硅薄锛涗笉甯﹀弬鐨勭敤鍒濆鍖杤alue鏋勫缓瀵硅薄銆?/p>
private Optional() {}
private Optional(T value) {}
浣嗘槸涓よ€呴兘鏄鏈夋柟娉曪紝鑰屽疄闄呬笂Optional鐨勫璞¢兘鏄€氳繃闈欐€佸伐鍘傛ā寮忕殑鏂瑰紡鏋勫缓锛屼富瑕佹湁浠ヤ笅涓変釜鍑芥暟
public static <T> Optional<T> of(T value) {}
public static <T> Optional<T> ofable(T value) {}
public static <T> Optional<T> empty() {}
鍒涘缓涓€涓竴瀹氫笉涓虹┖鐨凮ptional瀵硅薄锛屽洜涓哄鏋滀紶鍏ョ殑鍙傛暟涓虹┖浼氭姏鍑篘PE
Chestnut chestnut = new Chestnut();
Optional<Chestnut> opChest = Optional.of(chestnut);
鍒涘缓涓€涓┖鐨凮ptional瀵硅薄
Optional<Chestnut> opChest = Optional.empty();
鍒涘缓涓€涓彲绌虹殑Optional瀵硅薄
Chestnut chestnut = ;
Optional<Chestnut> opChest = Optional.ofable(chestnut);
姝e父浣跨敤鐨勬柟娉曞彲浠ヨ澶ц嚧鍒嗕负涓夌绫诲瀷锛屽垽鏂被銆佹搷浣滅被鍜屽彇鍊肩被
//鍒ゆ柇绫?/span>
public boolean isPresent() {}
//鎿嶄綔绫?/span>
public void ifPresent(Consumer<? super T> consumer) {}
//鍙栧€肩被
public T get() {}
public T orElse(T other) {}
public T orElseGet(Supplier<? extends T> other) {}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {}
isPresent()鏂规硶鍍忎竴涓畨鍏ㄩ榾锛屾帶鍒剁潃瀹瑰櫒涓殑value鍊兼槸绌鸿繕鏄湁鍊硷紝鐢ㄦ硶涓庡師鏈殑 !=obj鐨勭敤娉曠浉浼笺€傚綋obj鏈夊€艰繑鍥瀟rue锛屼负绌鸿繑鍥瀎alse锛堝嵆value鍊煎瓨鍦ㄤ负鐪燂級銆備絾涓€鑸疄鐜板垽鏂┖鎴栦笉涓虹┖鐨勯€昏緫锛屼娇鐢∣ptional鍏朵粬鐨勬柟娉曞鐞嗕細鏇翠负甯歌銆傚涓嬩唬鐮佸皢浼氭墦鍗板嚭娌℃湁鏍楀瓙鐨勬偛鎯ㄤ簨瀹炪€?/p>
Optional<Chestnut> opChest = ;
if(opChest.isPresent){
System.out.println("瀹瑰櫒閲屾病鏈夋牀瀛?);
}
ifPresent()鏂规硶鏄竴涓搷浣滅被鐨勬柟娉曪紝浠栫殑鍙傛暟鏄竴娈电洰鏍囩被鍨嬩负Consumer鐨勫嚱鏁帮紝褰搗alue涓嶄负绌烘椂锛岃嚜鍔ㄦ墽琛宑onsumer涓殑accept()鏂规硶锛堜紶鍏ユ椂瀹炵幇锛夛紝涓虹┖鍒欎笉鎵ц浠讳綍鎿嶄綔銆傛瘮濡備笅闈㈣繖娈典唬鐮侊紝鎴戜滑浼犲叆浜嗕竴娈佃緭鍑簐alue鐨刲amda琛ㄨ揪寮忥紝鎵撳嵃鍑轰簡鈥滆縼瑗挎澘鏍椻€濄€?/p>
Optional<Chestnut> opChest = Optional.ofable(new Chestnut("杩佽タ鏉挎牀"));
opChest.ifPresent(c -> System.out.println(c.getName()));
get()鏂规硶婧愮爜濡備笅锛屽彲浠ョ湅鍑猴紝get鐨勪綔鐢ㄦ槸鐩存帴杩斿洖瀹瑰櫒涓殑value銆備絾濡傛绮楁毚鐨勬柟娉曪紝浣跨敤鍓嶅鏋滀笉鍒ょ┖锛屽湪value涓虹┖鏃讹紝渚夸細姣笉鐣欐儏鍦版姏鍑轰竴涓紓甯搞€?/p>
public T get() {
if (value == ) {
throw new NoSuchElementException("No value present");
}
return value;
}
涓変釜orElse鏂规硶涓巊et鐩镐技锛屼篃閮藉睘浜庡彇鍊肩殑鎿嶄綔銆備笌get涓嶅悓涔嬪鍦ㄤ簬orElse鏂规硶涓嶇敤棰濆鐨勫垽绌鸿鍙ワ紝鎾板啓閫昏緫鏃舵瘮杈冩剦蹇€備笁涓猳rElse鐨勭浉鍚屼箣澶勬槸褰搗alue涓嶄负绌烘椂閮戒細杩斿洖value銆傚綋涓虹┖鏃讹紝鍒欏彟鏈夊悇鑷殑鎿嶄綔锛歰rElse()鏂规硶浼氳繑鍥炰紶鍏ョ殑other瀹炰緥锛堜篃鍙互涓篠upplier绫诲瀷鐨勫嚱鏁帮級锛沷rElseGet()鏂规硶浼氳嚜鍔ㄦ墽琛孲upplier绫诲瀷瀹炰緥鐨刧et()鏂规硶锛沷rElseThrow()鏂规硶浼氭姏鍑轰竴涓嚜瀹氱殑寮傚父銆傛洿鍏蜂綋鐨勫樊鍒細鍦ㄥ悗闈㈢殑鏂规硶瀵规瘮涓弿杩般€?br style="box-sizing: border-box;">濡備笅闈㈣繖娈典唬鐮侊紝灞曠ず浜嗗湪娌℃湁鏍楀瓙鐨勬椂鍊欙紝濡備綍鍚愬嚭鈥滀俊闃虫澘鏍椻€濄€佲€滈晣瀹夋澘鏍椻€濓紝浠ュ強鎶涘嚭鈥滄姽娌规牀瀛愨€濈殑璀﹀憡銆?/p>
Optional<Chestnut> opChest = Optional.empty();
System.out.println(opChest.orElse(new Chestnut("淇¢槼鏉挎牀")));
System.out.println(opChest.orElseGet(() -> new Chestnut("闀囧畨鏉挎牀")));
try {
opChest.orElseThrow(() -> new RuntimeException("鎶规补鏍楀瓙鍛€"));
}catch (RuntimeException e){
System.out.println(e.getMessage());
}
public Optional<T> filter(Predicate<? super T> predicate) {}
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {}
filter()鏂规硶鎺ュ彈璋撹瘝涓篜redicate绫诲瀷鐨勫嚱鏁颁綔涓哄弬鏁帮紝濡傛灉value鍊间笉涓虹┖鍒欒嚜鍔ㄦ墽琛宲redicate鐨則est()鏂规硶锛堜紶鍏ユ椂瀹炵幇锛夛紝鏉ュ垽鏂槸鍚︽弧瓒虫潯浠讹紝婊¤冻鍒欎細杩斿洖鑷韩Optional锛屼笉婊¤冻浼氳繑鍥炵┖Optional锛涘鏋渧alue鍊间负绌猴紝鍒欎細杩斿洖鑷韩Optional锛堝叾瀹炶窡绌篛ptional涔熷樊涓嶅锛夈€傚涓嬩唬鐮侊紝绗簩鍙ヤ腑绛涢€夋潯浠垛€滈偟搴楁澘鏍椻€濅笌opChest涓殑鏉挎牀鍚嶄笉绗︼紝娌℃湁閫氳繃杩囨护銆傝€岀涓夊彞鐨勭瓫閫夋潯浠朵笌opChest涓€鑷达紝鎵€浠ユ渶鍚庢墦鍗板嚭鏉ョ殑鏄€滃鍩庢澘鏍椻€濄€?/p>
Optional<Chestnut> opChest = Optional.ofable(new Chestnut("瀹藉煄鏉挎牀"));
opChest.filter(c -> "閭靛簵鏉挎牀".equals(c.getName())).ifPresent(System.out::println);
opChest.filter(c -> "瀹藉煄鏉挎牀".equals(c.getName())).ifPresent(System.out::println);
map()鍜宖latmap()鏂规硶浼犲叆鐨勯兘鏄竴涓狥unction绫诲瀷鐨勫嚱鏁帮紝map鍦ㄨ繖閲岀炕璇戜负鈥滄槧灏勨€濓紝褰搗alue鍊间笉涓虹┖鏃惰繘琛屼竴浜涘鐞嗭紝杩斿洖鐨勫€兼槸缁忚繃mapper鐨刟pply()鏂规硶澶勭悊鍚庣殑Optional绫诲瀷鐨勫€硷紝涓や釜鏂规硶鐨勭粨鏋滀竴鑷达紝澶勭悊杩囩▼涓細鏈夊樊鍒€傚涓嬩唬鐮侊紝浠巓pChest涓幏鍙栦簡鏉挎牀鍚嶅悗锛岄噸鏂皀ew浜嗕竴涓澘鏍楀彇鍚嶁€滈偄鍙版澘鏍椻€濓紝骞舵墦鍗板嚭鏉ワ紝涓よ€呰緭鍑轰竴鑷达紝澶勭悊褰㈠紡涓婃湁宸紓锛岃繖涓湪鍚庨潰鐨勬柟娉曞姣斾腑浼氬啀娆¤鍒般€?/p>
Optional<Chestnut> opChest = Optional.ofable(new Chestnut("閭㈠彴鏉挎牀"));
System.out.println(opChest.map(c -> new Chestnut(c.getName())));
System.out.println(opChest.flatMap(c -> Optional.ofable(new Chestnut(c.getName()))));
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {}
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {}
public Stream<T> stream() {}
JDK1.9涓鍔犱簡涓変釜鏂规硶锛歩fPresentOrElse() 銆乷r()鍜宻tream()鏂规硶銆?br style="box-sizing: border-box;">1.8鏃讹紝ifPresent()浠呮彁渚涗簡if(obj !=)鐨勬柟娉曪紝骞舵湭鎻愪緵if(obj !=)else{}鐨勬搷浣滐紝鎵€浠ュ湪1.9涓鍔犱簡涓€涓猧fPresentElse()鏂规硶锛屾彁渚涗簡杩欐柟闈㈢殑鏀寔銆傝鏂规硶鎺ユ敹涓や釜鍙傛暟Consumer鍜孯unnable绫诲瀷鐨勫嚱鏁帮紝褰搗alue涓嶄负绌猴紝璋冪敤action鐨刟ccept()鏂规硶锛岃繖鐐逛笌ifPresent()涓€鑷达紝褰搗alue涓虹┖鏃讹紝浼氳皟鐢╡mptyAction鐨剅un()鏂规硶锛屾墽琛宔lse璇箟鐨勯€昏緫銆傚涓嬮潰浠g爜锛屼細鎵撳嵃鍑衡€滄湪鏈夋牀瀛愨€濈殑鎻愮ず銆?/p>
Optional<Chestnut> opChest = Optional.empty();
opChest.ifPresentElse(c -> System.out.println(c.getName()),c -> System.out.println("鏈ㄦ湁鏍楀瓙鍛€"));
or()鏂规硶鏄綔涓簅rElse()鍜宱rElseGet()鏂规硶鐨勬敼杩涜€屽嚭鐜扮殑锛屼娇鐢ㄦ柟娉曚竴鑷达紝浣嗗悗涓や釜鏂规硶鍦ㄦ墽琛屽畬鎴愬悗杩斿洖鐨勫苟闈炲寘瑁呭€笺€傚鏋滈渶瑕佹墽琛屼竴浜涢€昏緫骞惰繑鍥濷ptional鏃讹紝鍙互浣跨敤or()鏂规硶銆傝鏂规硶浼犲叆Supplier鎺ュ彛鐨勫疄渚嬶紝褰搗alue鏈夊€兼椂鐩存帴杩斿洖鑷韩Optional锛屽綋涓虹┖鏃讹紝鑷姩鎵цsuuplier鐨刧et()鏂规硶锛屽苟鍖呰鎴怬ptional杩斿洖锛屽叾婧愮爜涓寘瑁呯殑璇彞濡備笅锛?/p>
Optional<T> r = (Optional<T>) supplier.get();
return Objects.requireNon(r);
stream()鏂规硶鍒欎笉鐢ㄥ璇达紝鏄竴涓彁渚涚粰娴佸紡缂栫▼浣跨敤鐨勬柟娉曪紝鍔熻兘涓婃槸涓€涓€傞厤鍣紝灏哋ptional杞崲鎴怱tream锛氭病鏈夊€艰繑鍥炰竴涓┖鐨剆tream锛屾垨鑰呭寘鍚竴涓狾ptional鐨剆tream銆傚叾婧愮爜濡備笅锛?/p>
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
Optional灏佽鐨勬柟娉曡緝澶氾紝閫夋嫨涓€涓悎閫傜殑鏂规硶鐨勫墠鎻愭槸瑕佷簡瑙e悇鑷€傜敤鐨勫満鏅拰寮傚悓
鐢变簬鏋勯€犲櫒涓虹鏈夋柟娉曪紝鍒涘缓瀵硅薄鍙兘閫氳繃闈欐€佸伐鍘傜殑鏂瑰紡鍒涘缓銆俹f()銆乷fable()鍜宔mpty()鏂规硶鏄笁涓潤鎬佹柟娉曘€傚厛涓婃簮鐮?/p>
//宸ュ巶鏂规硶
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofable(T value) {
return value == ? empty() : of(value);
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
//鏋勯€犳柟娉?/span>
private Optional() {
this.value = ;
}
private Optional(T value) {
this.value = Objects.requireNon(value);
}
//闈欐€佸父閲?/span>
private static final Optional<?> EMPTY = new Optional<>();
of()鏂规硶閫氳繃璋冪敤甯﹀弬鏋勯€狅紝new鍑轰竴涓狾ptional瀵硅薄锛屾甯稿舰鍙傚甫鍊兼槸涓嶄細鏈夐棶棰樼殑锛屼絾鏄綋褰㈠弬涓虹┖鏃讹紝璁剧疆value鍓嶇殑Objects.requireNon()闈炵┖鏍¢獙锛屽氨浼氭姏鍑轰竴涓紓甯革紝浠g爜濡備笅锛?/p>
public static <T> T requireNon(T obj) {
if (obj == )
throw new PointerException();
return obj;
}
requireNon()鏂规硶鏄痡ava.util鍖呬笅Objects绫荤殑涓€涓柟娉曪紝浣滅敤鏄鏌ヤ紶鍏ョ殑鍙傛暟鏄惁涓虹┖锛屼负绌轰細鎶涘嚭涓€涓狽PE锛屽湪Optional绫讳腑鐢ㄥ埌鐨勫湴鏂硅繕鏈夊緢澶氥€傛墍浠ュ彧鏈夌‘淇℃瀯閫燨ptional鎵€浼犲叆鐨勫弬鏁颁笉涓虹┖鏃舵墠鍙娇鐢╫f()鏂规硶銆?br style="box-sizing: border-box;">涓巓f()鐩稿鐨勮繕鏈変竴涓猳fable()鏂规硶锛岃鏂规硶鍏佽鎺ュ彈鍊兼瀯閫燨ptional锛屽綋褰㈠弬涓烘椂锛岃皟鐢╡mpty()鏂规硶锛岃€宔mpty()鏂规硶杩斿洖鐨勬槸涓€涓紪璇戞湡灏辩‘瀹氱殑甯搁噺EMPTY锛孍MPTY鍙栧€兼槸鏃犲弬鏋勯€犲櫒鍒涘缓瀵硅薄锛屾渶缁堝緱鍒扮殑鏄竴涓獀alue涓虹┖鐨凮ptional瀵硅薄銆?/p>
2.2)涓鍒帮紝姝e父浣跨敤鐨勬柟娉曚腑鏈夊睘浜庡彇鍊肩被鐨勬柟娉曪紝orElse()銆乷rElseGet()鍜宱rElseThrow()锛岃繖涓変釜鏂规硶鍦ㄩ潪绌烘椂鍧囪繑鍥瀡alue锛屼絾鏄负绌烘椂鐨勫鐞嗗悇涓嶇浉鍚屻€傚厛涓婃簮鐮侊細
public T orElse(T other) {
return value != ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != ? value : other.get();
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != ) {
return value;
} else {
throw exceptionSupplier.get();
}
}
orElse()鍜宱rElseGet()鏂规硶鏈€鐩磋鐨勫樊寮傛槸褰㈠弬鐨勪笉鍚岋紝鐪嬩笅闈竴娈典唬鐮侊細
//娴嬭瘯璇彞
Optional<Chestnut> opChest = Optional.ofable(new Chestnut("妗愭煆鏉挎牀"));
//Optional<Chestnut> opChest=Optional.empty();
opChest.orElse(print("orELse"));
opChest.orElseGet(()->print("orElseGet"));
//璋冪敤鏂规硶
private static Chestnut print(String method){
System.out.println("鐕曞北鏉挎牀鏈€濂藉悆----"+method);
return new Chestnut("鐕曞北鏉挎牀");
}
绗竴娆★紝new鍑轰竴涓€滄鏌忔澘鏍椻€濈殑Optional锛屽垎鍒皟鐢╫rElse()鍜宱rElseGet()鏂规硶锛岀粨鏋滃嚭鐜颁簡涓よ鐨勨€滅嚂灞辨澘鏍楁渶濂藉悆鈥濈殑杈撳嚭锛屽洜涓轰袱涓柟娉曞湪value涓嶄负鏃堕兘浼氭墽琛屽舰鍙備腑鐨勬柟娉曪紱
绗簩娆★紝閫氳繃empty()鏂规硶鑾峰緱涓€涓┖鏍楀瓙鐨凮ptional锛屽啀璋冪敤orElse()鍜宱rElseGet()鏂规硶锛岀粨鏋滃眳鐒惰繕鍑虹幇浜嗕竴琛屸€滅嚂灞辨澘鏍楁渶濂藉悆鈥濈殑杈撳嚭銆?/p>
绗竴娆¤緭鍑猴細
鐕曞北鏉挎牀鏈€濂藉悆----orELse
鐕曞北鏉挎牀鏈€濂藉悆----orElseGet
绗簩娆¤緭鍑猴細
鐕曞北鏉挎牀鏈€濂藉悆----orELse
鍏跺師鍥犳槸orElseGet()鐨勫弬鏁版槸Supplier鐩爣绫诲瀷鐨勫嚱鏁帮紝绠€鍗曟潵璇达紝Suppiler鎺ュ彛绫讳技Spring鐨勬噿鍔犺浇锛屽0鏄庝箣鍚庡苟涓嶄細鍗犵敤鍐呭瓨锛屽彧鏈夋墽琛屼簡get()鏂规硶涔嬪悗锛屾墠浼氳皟鐢ㄦ瀯閫犳柟娉曞垱寤哄嚭瀵硅薄锛岃€宱rElse()鏄揩鍔犺浇锛屽嵆浣挎病鏈夎皟鐢紝涔熶細瀹為檯鐨勮繍琛屻€?br style="box-sizing: border-box;">杩欎釜鐗规€у湪涓€浜涚畝鍗曠殑鏂规硶涓婂樊璺濅笉澶э紝浣嗘槸褰撴柟娉曟槸涓€浜涙墽琛屽瘑闆嗗瀷鐨勮皟鐢ㄦ椂锛屾瘮濡傝繙绋嬭皟鐢紝璁$畻绫绘垨鑰呮煡璇㈢被鏂规硶鏃讹紝浼氭崯鑰椾竴瀹氱殑鎬ц兘銆?br style="box-sizing: border-box;">orElseThrow()鏂规硶涓巓rElseGet()鏂规硶鐨勫弬鏁伴兘鏄疭upplier鍙傛暟閮芥槸鍑芥暟绫诲瀷鐨勶紝杩欐剰鍛崇潃杩欎袱绉嶆柟娉曢兘鏄噿鍔犺浇锛屼絾閽堝浜庡繀椤昏浣跨敤寮傚父鎺у埗娴佺▼鐨勫満鏅紝orElseThrow()浼氭洿鍔犲悎閫傦紝鍥犱负鍙互鎺у埗寮傚父绫诲瀷锛屼娇寰楃浉姣擭PE浼氭湁鏇翠赴瀵岀殑璇箟銆?/p>
a銆乵ap涓巉ilterMap
鍏堜笂婧愮爜锛?/p>
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNon(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofable(mapper.apply(value));
}
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNon(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNon(mapper.apply(value));
}
}
map()涓巉ilterMap()鐨勭浉鍚岀偣鏄紝閮芥帴鍙椾竴涓狥unction绫诲瀷鐨勫嚱鏁帮紝骞朵笖杩斿洖鍊奸兘鏄疧ptional绫诲瀷鐨勬暟鎹€備絾鏄粠婧愮爜涓垜浠篃鑳界湅鍑猴細
棣栧厛锛宮ap()鍦ㄨ繑鍥炴椂锛屼娇鐢ㄤ簡ofable()鍑芥暟瀵硅繑鍥炲€煎寘浜嗕竴灞傦紝杩欎釜鍑芥暟鍦?.1)宸茬粡璇磋繃锛屾槸涓€涓狾ptional鐨勫伐鍘傚嚱鏁帮紝浣滅敤鏄皢涓€涓暟鎹寘瑁呮垚Optional锛涜€宖ilterMap()杩斿洖鏃跺彧鏄仛浜嗛潪绌烘牎楠岋紝鍦ㄥ簲鐢╩apper.apply鏃跺氨宸茬粡鏄竴涓狾ptional绫诲瀷鐨勫璞°€?br style="box-sizing: border-box;">鍏舵锛屼粠绛惧悕涓篃鍙互鐪嬪嚭锛宮ap()鐨凢unction鐨勮緭鍑哄€兼槸鈥濓紵extends U鈥濓紝杩欐剰鍛崇潃鍦╩apper.apply()澶勭悊瀹屾垚鍚庯紝鍙鍚愬嚭涓€涓猆绫诲瀷鎴栬€匲绫诲瀷鐨勫瓙绫诲嵆鍙紱鑰宖ilterMap()鐨凢unctional鐨勮緭鍑哄€兼槸鈥淥ptional鈥濓紝鍒欏湪mapper.apply()澶勭悊瀹屾垚涔嬪悗锛岃繑鍥炵殑蹇呴』鏄竴涓狾ptional绫诲瀷鐨勬暟鎹€?/span>
b銆乮fPresent涓巌fPresentOrElse
ifPresentOrElse()鏂规硶鏄綔涓篿fPresent()鐨勬敼杩涙柟娉曞嚭鐜扮殑銆傚厛鐪嬫簮鐮侊細
public void ifPresent(Consumer<? super T> action) {
if (value != ) {
action.accept(value);
}
}
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
if (value != ) {
action.accept(value);
} else {
emptyAction.run();
}
}
浠庢簮鐮佷腑鍙互鐪嬪嚭锛宨fPresentOrElse()鍙傛暟澧炲姞浜嗕竴涓猂unnable绫诲瀷鐨勫嚱鏁癳mptyAction锛屽湪value !=鏃讹紝閮芥縺娲讳簡action.accept()鏂规硶銆傚彧鏄綋value==鏃讹紝ifPresentOrElse()鏂规硶杩樹細璋冪敤emptyAction.run()鏂规硶銆傛墍浠ユ€荤殑鏉ヨ锛宩dk1.9鍔犲叆ifPresentOrElse()鏂规硶锛屾槸浣滀负ifPreset鍦╥f-else棰嗗煙鐨勮ˉ鍏呭嚭鐜扮殑銆?/p>
c銆乷r涓巓rElse
鍚屾牱浣滀负鏀硅繘鐨刼r()鏂规硶涔熸槸涓轰簡瑙e喅orElse绯诲垪鏂规硶鐨勨€滃皬缂虹偣鈥濆嚭鐜扮殑锛屽厛鐪嬫簮鐮侊細
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNon(supplier);
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional<T> r = (Optional<T>) supplier.get();
return Objects.requireNon(r);
}
}
public T orElse(T other) {
return value != ? value : other;
}
public T orElseGet(Supplier<? extends T> supplier) {
return value != ? value : supplier.get();
}
or()鏂规硶鍦ㄧ鍚嶅舰寮忎笂鏇存帴杩憃rElseGet()锛屽嵆褰㈠弬閮芥槸Supplier绫诲瀷鐨勫嚱鏁帮紝浣嗘槸涓庡叾涓嶅悓鐨勬槸锛宱r()鏂规硶鍦ㄥ舰鍙備腑锛屾寚瀹氫簡Supplier杩斿洖鐨勭被鍨嬪繀椤讳负Optional绫诲瀷锛屼笖value鐨勭被鍨嬪繀椤讳负T鎴栬€匱鐨勫瓙绫汇€俹rElse绯诲垪鐨勬柟娉曪紝鏇村儚鏄竴绉嶆秷璐圭殑鏂规硶锛屼粠涓€涓狾ptional鐨勫疄渚嬩腑鈥滃彇鍑衡€渧alue鐨勫€艰繘鍏ヤ笅涓€姝ユ搷浣滐紝鑰宱r()鏂规硶鍒欏儚鏄缓閫犺€呮ā寮忥紝瀵箆alue鏈変竴瀹氱殑鎿嶄綔涔嬪悗锛岄噸鏂板悙鍑虹殑杩樻槸Optional绫诲瀷鐨勬暟鎹紝鎵€浠ヤ娇鐢ㄦ椂鍙互涓茶仈鍦ㄤ竴璧凤紝鍚庝竴涓猳r澶勭悊鍓嶄竴涓猳r鍚愬嚭鐨凮ptional銆?/p>
杩欓噷鎸囩殑鈥滃嵄闄┾€濇寚鐨勬槸浼氭姏鍑哄紓甯革紝姣曠珶寮曡繘Optional绫荤殑鐩殑灏辨槸鍘婚櫎瀵筃PE鐨勫垽鏂紝濡傛灉姝ゆ椂鍐嶆姏鍑轰竴涓狽PE鎴栬€呭叾浠栫殑寮傚父锛屾病鏈夊鐞嗗ソ灏变細涓虹▼搴忓紩鍏ヤ笉灏忕殑楹荤儲銆傛墍浠ュOptional涓彲鑳芥姏鍑哄紓甯哥殑鏂规硶鍋氫竴涓€荤粨銆?br style="box-sizing: border-box;">棣栧厛锛屾渶鐩磋鐨勪細鎶涘嚭寮傚父鐨勬柟娉曞氨鏄痮f()鏂规硶锛屽洜涓簅f鏂规硶浼氳皟鐢ㄥ甫鍙傛瀯閫犲垱寤哄疄渚嬶紝鑰屽甫鍙傛瀯閫犱腑鏈夊value闈炵┖鐨勬鏌ワ紝濡傛灉绌轰細鎶涘嚭NPE寮傚父锛?br style="box-sizing: border-box;">鍏舵锛実et()鏂规硶涔熸槸涓€涓€滃嵄闄┾€濈殑鏂规硶锛屽洜涓哄綋涓嶅垽绌虹洿鎺ヤ娇鐢╣et鍙栧€兼椂锛屼細瑙﹀彂get涓璑oSuchElementException寮傚父锛?br style="box-sizing: border-box;">鍐嶆锛宱rElseThrow()鏂规硶涔熶細鎶涘嚭寮傚父锛屼絾鏄繖绉嶅紓甯稿睘浜庝汉涓烘寚瀹氱殑寮傚父锛屾槸涓轰簡浣垮緱寮傚父鎯呭喌鐨勮涔夋洿鍔犱赴瀵岋紝鑰屼汉涓鸿缃殑锛屾槸涓€绉嶅彲鎺х殑寮傚父锛?br style="box-sizing: border-box;">鏈€鍚庯紝鍦ㄤ竴浜涙柟娉曚腑锛岃缃簡鍙傛暟闈炵┖妫€鏌ワ紙Objects.requireNon()锛夛紝杩欑妫€鏌ヤ細鎶涘嚭NPE寮傚父锛岄櫎鍘诲凡缁忔彁鍒扮殑甯﹀弬鏋勯€犲櫒锛岃繕鏈塮ilter銆乵ap銆乫latMap銆乷r杩欏洓涓柟娉曪紝濡傛灉浼犲叆鐨勬帴鍙e疄渚嬫槸鍊煎氨浼氶殢鏃跺紩鐖哊PE銆?/p>
a銆佸垵濮嬪寲涓?/strong>
绗竴绉嶈鐢ㄥ舰寮忔槸缁橭ptional绫诲瀷鐨勫彉閲忓垵濮嬪寲鐨勬椂鍊?Optional绫诲瀷鍙橀噺鏄粯璁や笉涓虹┖鐨勶紝鎵€浠ュ湪鍙栨柟娉曟墽琛岀殑鏃跺€欐墠鍙互鑲嗘棤蹇屾儺鈥濈偣鈥濆嚭鍘伙紝濡傛灉鍦ㄥ垵濮嬪寲鐨勬椂鍊欏嚭鐜帮細
Optional<Chestnut> chest = ;
骞朵笖涓嶅強鏃朵负chest璧嬪€硷紝鍒欒繕鏄鏄撳嚭鐜癗PE锛屾纭殑鍒濆鍖栨柟寮忓簲璇ユ槸锛?/p>
Optional<Chestnut> chest = Optional.empty();
b銆佺畝鍗曞垽绌?/strong> 浠g爜涓紝閫氳繃妫€鏌hestnut==鏉ュ鐞嗕负绌烘椂鐨勬儏鍐碉紝绠€鍗曚娇鐢╥sPresent()鏂规硶鍒ょ┖鐨勪唬鐮佸涓嬶細 閰卞┒鍎垮苟娌℃湁澶ぇ宸埆锛屾墍浠ュ湪浣跨敤Optional鏃讹紝棣栧厛搴旈伩鍏嶄娇鐢?Optional.isPresent() 鏉ユ鏌ュ疄渚嬫槸鍚﹀瓨鍦紝鍥犱负杩欑鏂瑰紡鍜?!=obj 娌℃湁鍖哄埆涔熸病浠€涔堟剰涔夈€?/p> c銆佺畝鍗昰et d銆佷綔涓哄睘鎬у瓧娈靛拰鏂规硶鍙傛暟 Reports any uses of java.util.Optional 澶ф剰鏄笉寤鸿濡傛浣跨敤Optional銆傜涓€锛屼笉寤鸿浣跨敤Optional浣滀负瀛楁鎴栧弬鏁帮紝鍏惰璁℃槸涓哄簱鏂规硶杩斿洖绫诲瀷鎻愪緵涓€绉嶆湁闄愮殑鏈哄埗锛岃€岃繖绉嶆満鍒跺彲浠ユ竻鏅扮殑琛ㄧず鈥滄病鏈夌粨鏋溾€濈殑璇箟锛涚浜岋紝Optional娌℃湁瀹炵幇Serilazable锛屾槸涓嶅彲琚簭鍒楀寲鐨勩€?br style="box-sizing: border-box;">杩欑璇敤鏂规硶姣旇緝鏄庢樉锛屽鐜板拰閬垮厤涔熸瘮杈冪畝鍗曘€備絾绗旇€呰繕鎯冲氨杩欎袱涓缓璁殑鍘熷洜鍋氳繘涓€姝ョ殑鎺㈢┒锛屾墍浠ユ煡闃呬簡涓€浜涜祫鏂欙紝澶т綋鐨勫師鍥犲涓嬶細 鍙鍦╯etter鏂规硶涓病鏈夊褰㈠弬鍋氱浉搴旂殑鏍¢獙锛岄偅涔堝垯闇€瑕佸湪浣跨敤鐨刧etFullName()鏂规硶涓紝澧炲姞瀵瑰睘鎬idName鐨勫垽绌烘搷浣滐紝鍥犱负瀹屽叏鍙兘閫氳繃setter鏂规硶浣垮緱灞炴€т负銆傚鏋滄妸鍒ょ┖绉诲埌setter鏂规硶涓紝涔熷苟娌℃湁鍑忓皯鍒ょ┖锛屼娇寰楀钩鐧芥尋杩涗簡涓€娈垫牱鏉夸唬鐮併€傚彟澶栧湪浼犲叆鏂规硶鏃讹紝涔熼渶瑕佸鍘熸湰鐨剉alue鍖呰涓€灞傚悗鍐嶄紶鍏ワ紝浣垮緱浠g爜鏄惧緱绱禈浜嗭紝濡備笅锛?/p> 鍦ㄥ睘鎬т笉涓篛ptional鐨勬椂鍊欙紝濡傛灉缁欏睘鎬ц祴鍊硷紝闇€瑕佷娇鐢ㄢ€滄秷璐光€濇搷浣滐紝姣斿orElse()锛屽彇鍑哄€煎啀璧嬬粰灞炴€э紝鐩告瘮鐩存帴浼犲叆String绫诲瀷鐨勫€间綔涓哄瓧娈靛拰褰㈠弬鍙互鍑忓皯杩欎簺姝ラ锛屽悗鑰呭弽鑰屾洿鍔犲悎閫傘€?/p> 绗簩涓師鍥狅紝涓轰粈涔堟病鏈夊疄鐜板簭鍒楀寲锛熺浉鍏冲彲浠ュ弬瑙丣ava Lamda鐨勪笓瀹剁粍璁ㄨ銆?br style="box-sizing: border-box;"> Value-Based Classes锛堝熀浜庡€肩殑绫伙級锛屼互涓嬫槸鏉ヨ嚜Java doc鐨勮В閲婏細 Some classes, such as java.util.Optional and java.time.LocalDateTime, are value-based. Instances of a value-based class: 瀹炶返涓父甯哥粍鍚堜娇鐢ㄤ互涓婂悇绉嶆柟娉曪紝涓斿緢澶氭柟娉曞父涓嶭ambda琛ㄨ揪寮忕粨鍚堬紝鑾峰彇鎯宠鐨勭粨鏋滐紝杩欓噷鍒楀嚭涓や釜甯歌鐨勪娇鐢ㄦ柟寮忥紝鍊肩被鍨嬭浆鎹㈠拰闆嗗悎鍏冪礌杩囨护銆?/p> a銆佺ず渚嬩竴 鍙互绠€鍖栨垚锛?/p> b銆佺ず渚嬩簩 鏈枃棣栧厛锛屼粠鎵€瑙e喅鐨勯棶棰樺紑濮嬶紝浠嬬粛浜嗗綋鍓峃PE澶勭悊鎵€閬囧埌鐨勯棶棰橈紱鐒跺悗锛屽垎绫诲湴浠嬬粛浜哋ptional绫讳腑鐨勬柟娉曞苟缁欏嚭鐩稿簲鐨勭ず渚嬶紱鎺ョ潃锛屼粠婧愮爜灞傞潰瀵瑰嚑涓父鐢ㄧ殑鏂规硶杩涜浜嗗姣旓紱鏈€鍚庯紝鍒椾妇鍑轰簡鍑犱釜甯歌鐨勮鐢ㄥ舰寮忓拰Best practice锛岀粨鏉熶簡鍏ㄦ枃銆?br style="box-sizing: border-box;">Optional绫诲叿鏈夛細鍙互鏄惧紡浣撶幇鍊煎彲鑳戒负绌虹殑璇箟鍜岄殣钘忓彲鑳藉瓨鍦ㄧ┖鎸囬拡鐨勪笉纭畾鎬х殑浼樼偣锛屼絾鏄悓鏃朵篃鍏锋湁锛岄€傜敤鑼冨洿涓嶆槸寰堝箍锛堝缓璁娇鐢ㄤ簬杩斿洖鍊煎拰NPE閫昏緫澶勭悊锛変互鍙婁娇鐢ㄦ椂闇€瑕佹洿澶氳€冮噺鐨勭己鐐广€?br style="box-sizing: border-box;">浣嗘槸鎬讳綋鐪嬫潵锛孫ptional绫绘槸浼撮殢Java8鍑芥暟寮忕紪绋嬪嚭鐜扮殑涓€椤规柊鐗规€с€備负澶勭悊閫昏緫鐨勫疄鐜版彁渚涗簡鏇村鐨勯€夋嫨锛屾湭鏉ユ湡寰呮洿澶氱殑瀹炶返鍜宐est practice鍑虹幇锛屼负Optional甯︽潵鏇村鍑哄満鐨勬満浼氥€?/p> [1] https://mp.weixin.qq.com/s/q_WmD3oMvgPhakiPLAq-CQ 鏉ユ簮:wechat 璋堣皥Tomcat杩炴帴鍣?/span> 鐖卞鑹哄熀浜嶴pringCloud鐨勯煣鎬ц兘鍔涘缓璁?/span> vivo缁熶竴鍛婅骞冲彴寤鸿涓庡疄璺?/span> 缇庡浘Android缂栬瘧閫熷害浼樺寲瀹炶返鎸囧崡 鍩轰簬etcd瀹炵幇澶ц妯℃湇鍔℃不鐞嗗簲鐢ㄥ疄鎴?/span> 鎶€鏈師鍒涘強鏋舵瀯瀹炶返鏂囩珷锛屾杩庨€氳繃鍏紬鍙疯彍鍗曘€岃仈绯绘垜浠€嶈繘琛屾姇绋裤€?/span>
绗簩绉嶆瘮杈冨父瑙佺殑璇敤褰㈠紡搴旇鏄娇鐢╥sPresent()鍋氱畝鍗曞垽绌恒€傚師鏈殑浠g爜濡備笅锛?/p>public String getName(Chestnut chestnut){
if(chestnut == ){
return "鏍楀瓙涓嶅瓨鍦?;
}else return chestnut.name();
}
public String getName(Chestnut chestnut){
Optional<Chestnut> opChest = Optional.ofable(chestnut);
if(!opChest.isPresent()){
return "鏍楀瓙涓嶅瓨鍦?;
}else return opChest.getname();
}
绗笁绉嶆瘮杈冨父瑙佺殑璇敤褰㈠紡鏄娇鐢∣ptional.get()鏂瑰紡鏉ヨ幏鍙朞ptional涓璿alue鐨勫€硷紝get()鏂规硶涓value==鐨勬儏鍐垫湁鎶涘嚭寮傚父锛屾墍浠ュ簲璇ュ湪鍋氬畬闈炵┖鏍¢獙涔嬪悗鍐嶄粠get鍙栧€硷紝鎴栬€呭崄鍒嗙‘瀹歷alue涓€瀹氫笉涓虹┖锛屽惁鍒欎細鍑虹幇NoSuchElementException鐨勫紓甯搞€傜浉瀵圭殑锛屽鏋滀笉鏄緢纭俊锛屽垯浣跨敤orElse()锛宱rElseGet()锛宱rElseThrow()鑾峰緱浣犵殑缁撴灉浼氭洿鍔犲悎閫傘€?/p>
绗洓绉嶈鐢ㄥ舰寮忓湪鍒濆Optional鐨勬椂鍊欏鏄撶鍒帮紝褰撴寚瀹氭煇涓被涓殑灞炴€э紝鎴栬€呮柟娉曠殑鍙傛暟涓篛ptional鐨勬椂鍊欙紝idea浼氱粰鍑哄涓嬫彁绀猴細
绗竴涓師鍥狅紝涓轰粈涔堜笉閫傚悎鍋氬睘鎬у瓧娈靛拰鏂规硶鍙傛暟锛熺洿鐧界殑璇达紝灏辨槸楹荤儲銆備负浜嗗紩鍏ptional锛屽嵈闇€瑕佸姞鍏ュ娈垫牱鏉夸唬鐮侊紝姣斿鍒ょ┖鎿嶄綔銆備娇寰楀湪涓嶅悎閫傜殑浣嶇疆浣跨敤Optional涓嶄粎娌℃湁缁欐垜浠甫鏉ヤ究鍒╋紝鍙嶈€岀害鏉熶簡鍐欎唬鐮佺殑閫昏緫銆?br style="box-sizing: border-box;">鍐欎互涓嬪煙妯″瀷浠g爜public class Chestnut {
private String firstName;
private Optional<String> midName = Optional.empty();
private String lastName;
public void setMidName(Optional<String> midName) {
this.midName = midName;
}
public String getFullName() {
String fullName = firstName;
if(midName != ) {
if(midName.isPresent()){
fullName = fullName.concat("." + midName.get());
}
return fullName.concat("." + lastName);
}
}
}
chest.setMidName(Optional.empty());
chest.setMidName(Optional.of("闃挎牀"));
JDK鍦ㄥ簭鍒楀寲涓婃瘮杈冪壒娈婏紝闇€瑕佸悓鏃跺吋椤惧悜鍓嶅拰鍚戝悗鍏煎锛屾瘮濡傚湪JDK7涓簭鍒楀寲鐨勫璞″簲璇ヨ兘澶熷湪JDK8涓弽搴忓垪鍖栵紝鍙嶄箣浜︾劧銆傚苟涓旓紝搴忓垪鍖栦緷璧栦簬瀵硅薄鐨刬dentity淇濇寔鍞竴鎬с€傚綋鍓峅ptional鏄紩鐢ㄧ被鍨嬬殑锛屼絾鍏惰鏍囪涓簐alue-based class锛堝熀浜庡€肩殑绫伙級锛屽苟涓旀湁璁″垝鍦ㄤ粖鍚庣殑鏌愪竴涓狫DK鐗堟湰涓疄鐜颁负value-based class锛屽彲瑙佷笂鍥俱€傚鏋滆璁捐涓哄彲搴忓垪鍖栵紝灏卞皢鍑虹幇涓や釜鐭涚浘鐐癸細1锛夊鏋淥ptional鍙簭鍒楀寲锛屽氨涓嶈兘灏哋ptional瀹炵幇涓簐alue-based class锛岃€屽繀椤绘槸寮曠敤绫诲瀷锛?锛夊惁鍒欏皢value-based class鍔犲叆鍚屼竴鎬х殑鏁忔劅鎿嶄綔锛堝寘鍚紩鐢ㄧ殑鐩哥瓑鎬у:==锛屽悓涓€鎬х殑hashcode鎴栬€呭悓姝ョ瓑锛夛紝浣嗘槸杩欎釜涓庡綋鍓嶅凡鍙戝竷鐨凧DK鐗堟湰閮芥槸鍐茬獊鐨勩€傛墍浠ョ患涓婏紝鑰冭檻鍒版湭鏉DK鐨勮鍒掑拰瀹炵幇鐨勫啿绐侊紝涓€寮€濮嬪氨灏哋ptional璁剧疆涓轰笉鍙簭鍒楀寲鐨勶紝搴旇鏄渶鍚堥€傜殑鏂规浜嗐€?/p>
1銆乤re final and immutable (though may contain references to mutable objects);
2銆乭ave implementations of equals, hashCode, and toString which are computed solely from the instance鈥檚 state and not from its identity or the state of any other object or variable;
3銆乵ake no use of identity-sensitive operations such as reference equality (==) between instances, identity hash code of instances, or synchronization on an instances鈥檚 intrinsic lock;
4銆乤re considered equal solely based on equals(), not based on reference equality (==);
5銆乨o not have accessible constructors, but are instead instantiated through factory methods which make no committment as to the identity of returned instances;
6銆乤re freely substitutable when equal, meaning that interchanging any two instances x and y that are equal according to equals() in any computation or method invocation should produce no visible change in behavior.
A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization, or any other identity-sensitive mechanism. Use of such identity-sensitive operations on instances of value-based classes may have unpredictable effects and should be avoided.2锛塀est practice
Chestnut chestnut = new Chestnut("閿ユ牀鏉挎牀");
if(chestnut != ){
String chestName = chestnut.getName();
if(chestName != ){
return chestName.concat("濂藉ソ鍚冿紒");
}
}else{
return ;
}
Chestnut chestnut = new Chestnut("閿ユ牀鏉挎牀");
return Optional.ofable(chestnut)
.map(Chestnut::getName)
.map(name->name.concat("濂藉ソ鍚冿紒"))
.orElse();
public static void main(String[] args) {
// 鍒涘缓涓€涓牀瀛愰泦鍚?/span>
List<Chestnut> chestList = new ArrayList<>();
// 鍒涘缓鍑犱釜鏍楀瓙
Chestnut chest1 = new Chestnut("abc");
Chestnut chest2 = new Chestnut("efg");
Chestnut chest3 = ;
// 灏嗘牀瀛愬姞鍏ラ泦鍚?/span>
chestList.add(chest1);
chestList.add(chest2);
chestList.add(chest3);
// 鍒涘缓鐢ㄤ簬瀛樺偍鏍楀瓙鍚嶇殑闆嗗悎
List<String> nameList = new ArrayList();
// 寰幆鏍楀瓙鍒楄〃鑾峰彇鏍楀瓙淇℃伅锛屽€艰幏鍙栦笉涓虹┖涓旀牀瀛愬悕浠モ€榓鈥欏紑澶?/span>
// 濡傛灉涓嶇鍚堟潯浠跺氨璁剧疆榛樿鍊硷紝鏈€鍚庡皢绗﹀悎鏉′欢鐨勬牀瀛愬悕鍔犲叆鏍楀瓙鍚嶉泦鍚?/span>
for (Chestnut chest : chestList) {
nameList.add(Optional.ofable(chest)
.map(Chestnut::getName)
.filter(value -> value.startsWith("a"))
.orElse("鏈~鍐?));
}
// 杈撳嚭鏍楀瓙鍚嶉泦鍚堜腑鐨勫€?/span>
System.out.println("閫氳繃 Optional 杩囨护鐨勯泦鍚堣緭鍑猴細");
nameList.stream().forEach(System.out::println);
}
5銆佹€荤粨
6銆佸弬鑰?/h2>
[2] https://www.runoob.com/java/java8-optional-class.html 鏉ユ簮:鑿滈笩鏁欑▼
[3] https://blog.csdn.net/qq_40741855/article/details/103251436 鏉ユ簮:CSDN
[4] https://yanbin.blog/java8-optional-several-common-incorrect-usages/#more-8824 鏉ユ簮:blog
[5] https://www.javaspecialists.eu/archive/Issue238-java.util.Optional---Short-Tutorial-by-Example.html 鏉ユ簮:java specialists
[6] Java鏍稿績鎶€鏈?鍗稩I - Java8鐨勬祦搴?- Optional绫诲瀷
[7] https://www.zhihu.com/question/444199629/answer/1729637041 鏉ユ簮:鐭ヤ箮
鉂?/span>
Hello锛佸皬浼欎即锛?/p>
闈炲父鎰熻阿鎮ㄩ槄璇绘捣杞扮殑鏂囩珷锛屽€樿嫢鏂囦腑鏈夐敊璇殑鍦版柟锛屾杩庢偍鎸囧嚭锝?/p>
鑷垜浠嬬粛 喱?喋娽禃藡)喋?/p>
鏄电О锛氭捣杞?/p>
鏍囩锛氱▼搴忕尶锝淐++閫夋墜锝滃鐢?/p>
绠€浠嬶細鍥燙璇█缁撹瘑缂栫▼锛岄殢鍚庤浆鍏ヨ绠楁満涓撲笟锛屾湁骞告嬁杩囦竴浜涘浗濂栥€佺渷濂?..宸蹭繚鐮斻€傜洰鍓嶆鍦ㄥ涔燙++/Linux/Python
瀛︿範缁忛獙锛氭墡瀹炲熀纭€ + 澶氬仛绗旇 + 澶氭暡浠g爜 + 澶氭€濊€?+ 瀛﹀ソ鑻辫锛?/p>
鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<section><span></span></section>
</body>
</html>
CSS
html,body{
margin: 0;
height: 100%;
}
body{
display: flex;
justify-content: center;
align-items: center;
background: #263238;
}
section {
width: 650px;
height: 300px;
padding: 10px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid red;
}
span {
width : 96px;
height: 96px;
border-radius: 50%;
display: inline-block;
position: relative;
border: 10px red;
border-style: dashed solid solid dotted;
border-bottom-color: transparent;
animation: rotation 2s linear infinite ;
}
span::after{
content: '';
position: absolute;
left: 51px;
top: 79px;
border: 20px solid transparent;
border-right-color: red;
transform: rotate(-45deg);
}
@keyframes rotation {
0% { transform: rotate(0deg) }
100% { transform: rotate(360deg)
}
}
浣跨敤span鏍囩浣滀负绠熬锛岃缃负
width : 96px;
height: 96px;
border: 10px red;
border-style: dashed solid solid dotted;
border-bottom-color: transparent;
鏁堟灉鍥惧涓?/span>
鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>
span鏍囩鍦嗚鍖?/span>
border-radius: 50%;
鏁堟灉鍥惧涓?/span>
鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>
浣跨敤span::after浼被鍏冪礌 浣滀负绠ご
璁剧疆涓?/span>
position: absolute;
border: 20px solid transparent;
border-right-color: red;
transform: rotate(-45deg);
鏁堟灉鍥惧涓?/span>
璁剧疆span::after鐨勪綅缃?/span>
娉細
/*杩欓噷绠ご闇€瑕佺Щ鍔ㄧ殑璺濈*/
left: 51px;
top: 79px;
鏁堟灉鍥惧涓?/span>
涓簊pan娣诲姞鍔ㄧ敾
animation: rotation 2s linear infinite ;
/*鍔ㄧ敾瀹炵幇*/
@keyframes rotation {
0% { transform: rotate(0deg) }
100% { transform: rotate(360deg)
}
}
鏁堟灉鍥惧涓?/span>
鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>
鏂囩珷浠呬綔涓哄涔犵瑪璁帮紝璁板綍浠?鍒?鐨勪竴涓繃绋嬨€?/span>
甯屾湜瀵规偍鏈夋墍甯姪锛屽鏈夐敊璇杩庡皬浼欎即鎸囨锝?/span>
鎯宠瘉鏄庝綘鐨勮剳鍔涘悧锛?/p>
浣犳兂閿荤偧鈥淚Q鈥濆悧锛?/p>
浣犳兂鎴愪负绁炵粡鐥呭悧锛?/p>
鍢橈紝鍏堝埆璇达紝鍏堟潵鐪嬬湅
杩欐湰绁炵粡鐥呯锛坹ou锛夌睄锛坸i锛夊惂锛侊紒
鍦ㄦ寮忓紑濮嬩慨鐐煎墠锛屽厛绉戞櫘涓嬭繖涓绫嶇殑淇偧鏂规硶锛?/p>
鍚屾椂浣跨敤宸﹀彸鎵嬪畬鎴愪笉鍚岀殑鎿嶄綔浠ラ€氳繃娓告垙銆?/p>
锛堝悓鏃跺乏鎵嬬敾鏂癸紝鍙虫墜鐢诲渾璇曡瘯锛屼綘灏遍€犺鍜嬬帺鍟~锛?/p>
鐭ラ亾鎬庝箞鐜╀簡锛屽氨寮€濮嬭窡鐫€灏忕紪寮€濮嬩慨鐐煎惂~~
姝ょ绫嶅垎涓?/p>
鈥滃叧鍗♀€濃€滄寫鎴樷€濅互鍙娾€滄垜鏄柉瀛愨€?/p>
涓夊ぇ淇偧闃舵锛?/p>
姣忎竴闃舵鍙堝唴缃€滆彍楦熲€濃€滀竴鑸€濃€滃洶闅锯€濃€滀笓瀹垛€濅互鍙娾€滄寫鎴樺ぇ甯堚€濅簲涓皬闃舵锛?/p>
姣忎釜灏忛樁娈靛張鍚勮嚜鏈?0涓叧鍗★紝
姣斿鑿滈笩闃舵浣犻渶瑕佷粠1鎵撳埌10鎵嶈兘鏅嬪崌涓€鑸樁娈碉紒
浠ユ绫绘帹~
瀛楁瘮杈冧笐锛屽氨铔湅涓€鍝堝惂~~
寮€濮嬬帺娓告垙鍚э紒锛?/p>
https://v.qq.com/x/page/i0383m832pw.html
浠庤彍楦?寮€濮嬬帺璧穨
鍙戠幇杩樻尯绠€鍗曠殑鍢泘
鎱㈡參鐨勫埌鑿滈笩3锛岀溂鐫涜窡涓嶄笂閫熷害鍟︼紒
涓嶆槸宸﹁竟灏忎汉姝诲氨鏄彸杈瑰皬浜烘锛侊紒
濂戒笉瀹规槗杩囦簡锛屽埌鑿滈笩4涓€杈硅鈥滄墦涔掍箵鈥濆彟涓€杈硅繕瑕佹壘涓嶅悓锛?/p>
澶╁摢锛侊紝瀵逛簬杞诲害鑴戞畫锛岄噸搴︽墜娈嬬殑灏忕紪瀹炲湪鏄湁鐐?strong>鍥伴毦鍟婏紒锛?/p>
鍙儨灏忕紪杩樻病杈惧埌灏卞揩瑕佷慨鐐兼垚绁炵粡鐥呬簡锛?/p>
涓嶈繃鐣ユ棤鑰荤殑灏忕紪鍙戠幇
鍙互鎵句釜浜鸿窡鍜变竴璧风帺鍟妦~
锛堝杺鍠傚杺锛佽繖鍙槸鍙樼浉浣滃紛鍛€锛侊級
姣曠珶锛屾父鎴忚繕鏄浜哄涓€璧锋墠濂界帺鍢涳紒
涓嶈繃鐪嬪埌浼楀鍚岄亾涓汉鐜╂垚鈥滆剳瑁傗€濇偅鑰?/p>
灏忕紪杩樻槸鐩稿綋娆f叞鐨剘~
O(鈭鈭?O鍝堝搱~
鍙€滅殑濞儈閮界帺杩涘尰闄\(鈮р柦鈮?/~鍟﹀暒鍟?/p>
铔嬬鐨勫績鎯呮槸鍜嬫牱鐨勶紵
灏忕紪寰堟槸濂藉鍛€( 鈯?o 鈯?)锛?/p>
娓湡鐨勶紝杩欐父鎴忔槸寮€鍙戞櫤鍔涢敾鐐煎乏鍙虫墜鐨勮秴绾х绫?/p>
涓嶈鐘硅鲍
蹇潵璺熷皬缂栦竴璧峰彉鑴戞畫鍟妦~
END
鏈湡缂栬緫锛氬皬瀹噝one 銆?/p>
瀹囧畽杈d箞澶ф€绘湁涓€娆鹃€楁瘮閫傚悎浣犮€?/p>
鍞犲棏锛屾墦娓告垙...鎵€鏈変笉鍔℃涓氱殑浜嬫儏璇疯仈绯绘垜銆?/p>
*请认真填写需求信息,我们会在24小时内与您取得联系。