整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

深入JDK中的Optional

娣卞叆JDK涓殑Optional

姒傝堪锛歄ptional鏈€鏃╂槸Google鍏徃Guava涓殑姒傚康锛屼唬琛ㄧ殑鏄彲閫夊€笺€侽ptional绫讳粠Java8鐗堟湰寮€濮嬪姞鍏ヨ豹鍗庡椁愶紝涓昏涓轰簡瑙e喅绋嬪簭涓殑NPE闂锛屼粠鑰屼娇寰楁洿灏戠殑鏄惧紡鍒ょ┖锛岄槻姝唬鐮佹薄鏌擄紝鍙︿竴鏂归潰锛屼篃浣垮緱棰嗗煙妯″瀷涓墍闅愯棌鐨勭煡璇嗭紝寰椾互鏄惧紡浣撶幇鍦ㄤ唬鐮佷腑銆侽ptional绫讳綅浜巎ava.util鍖呬笅锛屽閾惧紡缂栫▼椋庢牸鏈変竴瀹氱殑鏀寔銆傚疄闄呬笂锛孫ptional鏇村儚鏄竴涓鍣紝鍏朵腑瀛樻斁鐨勬垚鍛樺彉閲忔槸涓€涓猅绫诲瀷鐨剉alue锛屽彲鍊煎彲锛屼娇鐢ㄧ殑鏄疻rapper妯″紡锛屽value鎿嶄綔杩涜浜嗗寘瑁呬笌璁捐銆傛湰鏂囧皢浠嶰ptional鎵€瑙e喅鐨勯棶棰樺紑濮嬶紝閫愬眰瑙e墫锛岀敱娴呭叆娣憋紝鏂囦腑浼氬嚭鐜癘ptioanl鏂规硶涔嬮棿鐨勫姣旓紝瀹炶返锛岃鐢ㄦ儏鍐靛垎鏋愶紝浼樼己鐐圭瓑銆備笌澶у涓€璧凤紝瀵硅繖椤笿ava8涓殑鏂扮壒鎬э紝杩涜鐞嗚В鍜屾繁鍏ャ€?/p>

1銆佽В鍐崇殑闂

鑷悕鏄憲鐨勭┖鎸囬拡寮傚父锛屾槸姣忎釜绋嬪簭鍛橀兘浼氶亣鍒扮殑涓€绉嶅父瑙佸紓甯革紝浠讳綍璁块棶瀵硅薄鐨勬柟娉曚笌灞炴€х殑璋冪敤锛岄兘鍙兘浼氬嚭鐜癙ointException锛屽鏋滆纭繚涓嶈Е鍙戝紓甯革紝鎴戜滑閫氬父闇€瑕佽繘琛屽璞$殑鍒ょ┖鎿嶄綔銆?br style="box-sizing: border-box;">涓句釜鏍楀瓙锛屾湁涓€涓汉锛圫hopper锛夎繘瓒呭競璐墿锛屽彲鑳戒細鐢ㄨ喘鐗╄溅锛圱rolley锛変篃鍙兘浼氱敤鍏跺畠鏂瑰紡锛岃喘鐗╄溅閲屽彲鑳戒細鏈変竴琚嬫牀瀛愶紙Chestnut锛夛紝涔熷彲鑳芥病鏈夈€備笁鑰呭畾涔夌殑浠g爜濡備笅锛?/p>

  1. public class Shopper {

  2. private Trolley trolley;

  3. public Trolley getTrolley(){

  4. return trolley;

  5. }

  6. }

  7. public class Trolley {

  8. private Chestnut chestnut;

  9. public Chestnut getChestnut(){

  10. return chestnut;

  11. }

  12. }

  13. public class Chestnut {

  14. private String name;

  15. public String getName(){

  16. return name;

  17. }

  18. }

杩欐椂鎯宠鑾峰緱璐墿杞︿腑鏍楀瓙鐨勫悕绉帮紝鍍忎笅闈㈣繖涔堝啓锛屽氨鍙兘浼氳鍒版垜浠殑鈥滆€佹湅鍙嬧€濓紙NPE锛?/p>

  1. public String result(Shopper shopper){

  2. return shopper.getTrolley().getChestnut().getName();

  3. }

涓轰簡鑳介伩鍏嶅嚭鐜扮┖鎸囬拡寮傚父锛岄€氬父鐨勫啓娉曚細閫愬眰鍒ょ┖锛堝灞傚祵濂楁硶锛夛紝濡備笅

  1. public String result(Shopper shopper) {

  2. if (shopper != ) {

  3. Trolley trolley = shopper.getTrolley();

  4. if (trolley != ) {

  5. Chestnut chestnut = trolley.getChestnut();

  6. if (chestnut != ) {

  7. return chestnut.getName();

  8. }

  9. }

  10. }

  11. return "鑾峰彇澶辫触杈?;

  12. }

澶氬眰宓屽鐨勬柟娉曞湪瀵硅薄绾ц仈鍏崇郴姣旇緝娣辩殑鏃跺€欎細鐪嬬殑鐪艰姳缂贡鐨勶紝灏ゅ叾鏄偅涓€灞備竴灞傜殑鎷彿馃槖锛涘彟澶栧嚭閿欑殑鍘熷洜涔熷洜涓虹己涔忓搴斾俊鎭€岃妯$硦锛堜緥濡倀rolley涓虹┖鏃朵篃鍙繑鍥炰簡鏈€鍚庣殑鑾峰彇澶辫触銆傚綋鐒朵篃鍙互鍦ㄦ瘡涓€灞傚鍔爎eturn锛岀浉搴旂殑浠g爜鏈変細鍙樺緱寰堝啑闀匡級锛屾墍浠ユ鏃舵垜浠篃鍙互鐢ㄩ亣绌哄垯杩斿洖鐨勫崼璇彞杩涜鏀瑰啓銆?/p>

  1. public String result(Shopper shopper) {

  2. if (shopper == ) {

  3. return "璐墿鑰呬笉瀛樺湪";

  4. }

  5. Trolley trolley = shopper.getTrolley();

  6. if (trolley == ) {

  7. return "璐墿杞︿笉瀛樺湪";

  8. }

  9. Chestnut chestnut = trolley.getChestnut();

  10. if (chestnut == ) {

  11. return "鏍楀瓙涓嶅瓨鍦?;

  12. }

  13. return chestnut.getName();

  14. }

涓轰簡鍙栦竴涓悕瀛楄繘琛屼簡涓夋鏄剧ず鍒ょ┖鎿嶄綔锛岃繖鏍风殑浠g爜褰撶劧娌℃湁闂锛屼絾鏄紭绉€鐨勫伐绋嬪笀浠€绘槸甯屾湜鑳借幏寰楁洿浼橀泤绠€娲佺殑浠g爜銆侽ptional灏辨彁渚涗簡涓€浜涙柟娉曪紝瀹炵幇浜嗚繖鏍风殑鏈熸湜銆?/p>

  1. public String result(Shopper shopper){

  2. return Optional.ofable(shopper)

  3. .map(Shopper::getTrolley)

  4. .map(Trolley::getChestnut)

  5. .map(Chestnut::getName)

  6. .orElse("鑾峰彇澶辫触杈?);

  7. }

2銆佸父鐢ㄦ柟娉?/h2>

1锛夎幏寰桹ptional瀵硅薄

Optional绫讳腑鏈変袱涓瀯閫犳柟娉曪細甯﹀弬鍜屼笉甯﹀弬鐨勩€傚甫鍙傜殑灏嗕紶鍏ョ殑鍙傛暟璧嬪€紇alue锛屼粠鑰屾瀯寤篛ptional瀵硅薄锛涗笉甯﹀弬鐨勭敤鍒濆鍖杤alue鏋勫缓瀵硅薄銆?/p>

  1. private Optional() {}

  2. private Optional(T value) {}

浣嗘槸涓よ€呴兘鏄鏈夋柟娉曪紝鑰屽疄闄呬笂Optional鐨勫璞¢兘鏄€氳繃闈欐€佸伐鍘傛ā寮忕殑鏂瑰紡鏋勫缓锛屼富瑕佹湁浠ヤ笅涓変釜鍑芥暟

  1. public static <T> Optional<T> of(T value) {}

  2. public static <T> Optional<T> ofable(T value) {}

  3. public static <T> Optional<T> empty() {}

鍒涘缓涓€涓竴瀹氫笉涓虹┖鐨凮ptional瀵硅薄锛屽洜涓哄鏋滀紶鍏ョ殑鍙傛暟涓虹┖浼氭姏鍑篘PE

  1. Chestnut chestnut = new Chestnut();

  2. Optional<Chestnut> opChest = Optional.of(chestnut);

鍒涘缓涓€涓┖鐨凮ptional瀵硅薄

  1. Optional<Chestnut> opChest = Optional.empty();

鍒涘缓涓€涓彲绌虹殑Optional瀵硅薄

  1. Chestnut chestnut = ;

  2. Optional<Chestnut> opChest = Optional.ofable(chestnut);

2锛夋甯镐娇鐢?/h4>

姝e父浣跨敤鐨勬柟娉曞彲浠ヨ澶ц嚧鍒嗕负涓夌绫诲瀷锛屽垽鏂被銆佹搷浣滅被鍜屽彇鍊肩被

  1. //鍒ゆ柇绫?/span>

  2. public boolean isPresent() {}

  3. //鎿嶄綔绫?/span>

  4. public void ifPresent(Consumer<? super T> consumer) {}

  5. //鍙栧€肩被

  6. public T get() {}

  7. public T orElse(T other) {}

  8. public T orElseGet(Supplier<? extends T> other) {}

  9. public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {}

isPresent()鏂规硶鍍忎竴涓畨鍏ㄩ榾锛屾帶鍒剁潃瀹瑰櫒涓殑value鍊兼槸绌鸿繕鏄湁鍊硷紝鐢ㄦ硶涓庡師鏈殑 !=obj鐨勭敤娉曠浉浼笺€傚綋obj鏈夊€艰繑鍥瀟rue锛屼负绌鸿繑鍥瀎alse锛堝嵆value鍊煎瓨鍦ㄤ负鐪燂級銆備絾涓€鑸疄鐜板垽鏂┖鎴栦笉涓虹┖鐨勯€昏緫锛屼娇鐢∣ptional鍏朵粬鐨勬柟娉曞鐞嗕細鏇翠负甯歌銆傚涓嬩唬鐮佸皢浼氭墦鍗板嚭娌℃湁鏍楀瓙鐨勬偛鎯ㄤ簨瀹炪€?/p>

  1. Optional<Chestnut> opChest = ;

  2. if(opChest.isPresent){

  3. System.out.println("瀹瑰櫒閲屾病鏈夋牀瀛?);

  4. }

ifPresent()鏂规硶鏄竴涓搷浣滅被鐨勬柟娉曪紝浠栫殑鍙傛暟鏄竴娈电洰鏍囩被鍨嬩负Consumer鐨勫嚱鏁帮紝褰搗alue涓嶄负绌烘椂锛岃嚜鍔ㄦ墽琛宑onsumer涓殑accept()鏂规硶锛堜紶鍏ユ椂瀹炵幇锛夛紝涓虹┖鍒欎笉鎵ц浠讳綍鎿嶄綔銆傛瘮濡備笅闈㈣繖娈典唬鐮侊紝鎴戜滑浼犲叆浜嗕竴娈佃緭鍑簐alue鐨刲amda琛ㄨ揪寮忥紝鎵撳嵃鍑轰簡鈥滆縼瑗挎澘鏍椻€濄€?/p>

  1. Optional<Chestnut> opChest = Optional.ofable(new Chestnut("杩佽タ鏉挎牀"));

  2. opChest.ifPresent(c -> System.out.println(c.getName()));

get()鏂规硶婧愮爜濡備笅锛屽彲浠ョ湅鍑猴紝get鐨勪綔鐢ㄦ槸鐩存帴杩斿洖瀹瑰櫒涓殑value銆備絾濡傛绮楁毚鐨勬柟娉曪紝浣跨敤鍓嶅鏋滀笉鍒ょ┖锛屽湪value涓虹┖鏃讹紝渚夸細姣笉鐣欐儏鍦版姏鍑轰竴涓紓甯搞€?/p>

  1. public T get() {

  2. if (value == ) {

  3. throw new NoSuchElementException("No value present");

  4. }

  5. return value;

  6. }

涓変釜orElse鏂规硶涓巊et鐩镐技锛屼篃閮藉睘浜庡彇鍊肩殑鎿嶄綔銆備笌get涓嶅悓涔嬪鍦ㄤ簬orElse鏂规硶涓嶇敤棰濆鐨勫垽绌鸿鍙ワ紝鎾板啓閫昏緫鏃舵瘮杈冩剦蹇€備笁涓猳rElse鐨勭浉鍚屼箣澶勬槸褰搗alue涓嶄负绌烘椂閮戒細杩斿洖value銆傚綋涓虹┖鏃讹紝鍒欏彟鏈夊悇鑷殑鎿嶄綔锛歰rElse()鏂规硶浼氳繑鍥炰紶鍏ョ殑other瀹炰緥锛堜篃鍙互涓篠upplier绫诲瀷鐨勫嚱鏁帮級锛沷rElseGet()鏂规硶浼氳嚜鍔ㄦ墽琛孲upplier绫诲瀷瀹炰緥鐨刧et()鏂规硶锛沷rElseThrow()鏂规硶浼氭姏鍑轰竴涓嚜瀹氱殑寮傚父銆傛洿鍏蜂綋鐨勫樊鍒細鍦ㄥ悗闈㈢殑鏂规硶瀵规瘮涓弿杩般€?br style="box-sizing: border-box;">濡備笅闈㈣繖娈典唬鐮侊紝灞曠ず浜嗗湪娌℃湁鏍楀瓙鐨勬椂鍊欙紝濡備綍鍚愬嚭鈥滀俊闃虫澘鏍椻€濄€佲€滈晣瀹夋澘鏍椻€濓紝浠ュ強鎶涘嚭鈥滄姽娌规牀瀛愨€濈殑璀﹀憡銆?/p>

  1. Optional<Chestnut> opChest = Optional.empty();

  2. System.out.println(opChest.orElse(new Chestnut("淇¢槼鏉挎牀")));

  3. System.out.println(opChest.orElseGet(() -> new Chestnut("闀囧畨鏉挎牀")));

  4. try {

  5. opChest.orElseThrow(() -> new RuntimeException("鎶规补鏍楀瓙鍛€"));

  6. }catch (RuntimeException e){

  7. System.out.println(e.getMessage());

  8. }

3锛夎繘闃朵娇鐢?/h4>
  1. public Optional<T> filter(Predicate<? super T> predicate) {}

  2. public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {}

  3. public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {}

filter()鏂规硶鎺ュ彈璋撹瘝涓篜redicate绫诲瀷鐨勫嚱鏁颁綔涓哄弬鏁帮紝濡傛灉value鍊间笉涓虹┖鍒欒嚜鍔ㄦ墽琛宲redicate鐨則est()鏂规硶锛堜紶鍏ユ椂瀹炵幇锛夛紝鏉ュ垽鏂槸鍚︽弧瓒虫潯浠讹紝婊¤冻鍒欎細杩斿洖鑷韩Optional锛屼笉婊¤冻浼氳繑鍥炵┖Optional锛涘鏋渧alue鍊间负绌猴紝鍒欎細杩斿洖鑷韩Optional锛堝叾瀹炶窡绌篛ptional涔熷樊涓嶅锛夈€傚涓嬩唬鐮侊紝绗簩鍙ヤ腑绛涢€夋潯浠垛€滈偟搴楁澘鏍椻€濅笌opChest涓殑鏉挎牀鍚嶄笉绗︼紝娌℃湁閫氳繃杩囨护銆傝€岀涓夊彞鐨勭瓫閫夋潯浠朵笌opChest涓€鑷达紝鎵€浠ユ渶鍚庢墦鍗板嚭鏉ョ殑鏄€滃鍩庢澘鏍椻€濄€?/p>

  1. Optional<Chestnut> opChest = Optional.ofable(new Chestnut("瀹藉煄鏉挎牀"));

  2. opChest.filter(c -> "閭靛簵鏉挎牀".equals(c.getName())).ifPresent(System.out::println);

  3. opChest.filter(c -> "瀹藉煄鏉挎牀".equals(c.getName())).ifPresent(System.out::println);

map()鍜宖latmap()鏂规硶浼犲叆鐨勯兘鏄竴涓狥unction绫诲瀷鐨勫嚱鏁帮紝map鍦ㄨ繖閲岀炕璇戜负鈥滄槧灏勨€濓紝褰搗alue鍊间笉涓虹┖鏃惰繘琛屼竴浜涘鐞嗭紝杩斿洖鐨勫€兼槸缁忚繃mapper鐨刟pply()鏂规硶澶勭悊鍚庣殑Optional绫诲瀷鐨勫€硷紝涓や釜鏂规硶鐨勭粨鏋滀竴鑷达紝澶勭悊杩囩▼涓細鏈夊樊鍒€傚涓嬩唬鐮侊紝浠巓pChest涓幏鍙栦簡鏉挎牀鍚嶅悗锛岄噸鏂皀ew浜嗕竴涓澘鏍楀彇鍚嶁€滈偄鍙版澘鏍椻€濓紝骞舵墦鍗板嚭鏉ワ紝涓よ€呰緭鍑轰竴鑷达紝澶勭悊褰㈠紡涓婃湁宸紓锛岃繖涓湪鍚庨潰鐨勬柟娉曞姣斾腑浼氬啀娆¤鍒般€?/p>

  1. Optional<Chestnut> opChest = Optional.ofable(new Chestnut("閭㈠彴鏉挎牀"));

  2. System.out.println(opChest.map(c -> new Chestnut(c.getName())));

  3. System.out.println(opChest.flatMap(c -> Optional.ofable(new Chestnut(c.getName()))));

4锛?.9鏂板

  1. public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {}

  2. public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {}

  3. 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>

  1. Optional<Chestnut> opChest = Optional.empty();

  2. opChest.ifPresentElse(c -> System.out.println(c.getName()),c -> System.out.println("鏈ㄦ湁鏍楀瓙鍛€"));

or()鏂规硶鏄綔涓簅rElse()鍜宱rElseGet()鏂规硶鐨勬敼杩涜€屽嚭鐜扮殑锛屼娇鐢ㄦ柟娉曚竴鑷达紝浣嗗悗涓や釜鏂规硶鍦ㄦ墽琛屽畬鎴愬悗杩斿洖鐨勫苟闈炲寘瑁呭€笺€傚鏋滈渶瑕佹墽琛屼竴浜涢€昏緫骞惰繑鍥濷ptional鏃讹紝鍙互浣跨敤or()鏂规硶銆傝鏂规硶浼犲叆Supplier鎺ュ彛鐨勫疄渚嬶紝褰搗alue鏈夊€兼椂鐩存帴杩斿洖鑷韩Optional锛屽綋涓虹┖鏃讹紝鑷姩鎵цsuuplier鐨刧et()鏂规硶锛屽苟鍖呰鎴怬ptional杩斿洖锛屽叾婧愮爜涓寘瑁呯殑璇彞濡備笅锛?/p>

  1. Optional<T> r = (Optional<T>) supplier.get();

  2. return Objects.requireNon(r);

stream()鏂规硶鍒欎笉鐢ㄥ璇达紝鏄竴涓彁渚涚粰娴佸紡缂栫▼浣跨敤鐨勬柟娉曪紝鍔熻兘涓婃槸涓€涓€傞厤鍣紝灏哋ptional杞崲鎴怱tream锛氭病鏈夊€艰繑鍥炰竴涓┖鐨剆tream锛屾垨鑰呭寘鍚竴涓狾ptional鐨剆tream銆傚叾婧愮爜濡備笅锛?/p>

  1. if (!isPresent()) {

  2. return Stream.empty();

  3. } else {

  4. return Stream.of(value);

  5. }

3銆佹柟娉曞姣斿拰鎬荤粨

Optional灏佽鐨勬柟娉曡緝澶氾紝閫夋嫨涓€涓悎閫傜殑鏂规硶鐨勫墠鎻愭槸瑕佷簡瑙e悇鑷€傜敤鐨勫満鏅拰寮傚悓

1锛夊垱寤烘柟娉曠殑瀵规瘮

鐢变簬鏋勯€犲櫒涓虹鏈夋柟娉曪紝鍒涘缓瀵硅薄鍙兘閫氳繃闈欐€佸伐鍘傜殑鏂瑰紡鍒涘缓銆俹f()銆乷fable()鍜宔mpty()鏂规硶鏄笁涓潤鎬佹柟娉曘€傚厛涓婃簮鐮?/p>

  1. //宸ュ巶鏂规硶

  2. public static <T> Optional<T> of(T value) {

  3. return new Optional<>(value);

  4. }


  5. public static <T> Optional<T> ofable(T value) {

  6. return value == ? empty() : of(value);

  7. }


  8. public static<T> Optional<T> empty() {

  9. @SuppressWarnings("unchecked")

  10. Optional<T> t = (Optional<T>) EMPTY;

  11. return t;

  12. }

  13. //鏋勯€犳柟娉?/span>

  14. private Optional() {

  15. this.value = ;

  16. }

  17. private Optional(T value) {

  18. this.value = Objects.requireNon(value);

  19. }

  20. //闈欐€佸父閲?/span>

  21. private static final Optional<?> EMPTY = new Optional<>();

of()鏂规硶閫氳繃璋冪敤甯﹀弬鏋勯€狅紝new鍑轰竴涓狾ptional瀵硅薄锛屾甯稿舰鍙傚甫鍊兼槸涓嶄細鏈夐棶棰樼殑锛屼絾鏄綋褰㈠弬涓虹┖鏃讹紝璁剧疆value鍓嶇殑Objects.requireNon()闈炵┖鏍¢獙锛屽氨浼氭姏鍑轰竴涓紓甯革紝浠g爜濡備笅锛?/p>

  1. public static <T> T requireNon(T obj) {

  2. if (obj == )

  3. throw new PointerException();

  4. return obj;

  5. }

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.2)涓鍒帮紝姝e父浣跨敤鐨勬柟娉曚腑鏈夊睘浜庡彇鍊肩被鐨勬柟娉曪紝orElse()銆乷rElseGet()鍜宱rElseThrow()锛岃繖涓変釜鏂规硶鍦ㄩ潪绌烘椂鍧囪繑鍥瀡alue锛屼絾鏄负绌烘椂鐨勫鐞嗗悇涓嶇浉鍚屻€傚厛涓婃簮鐮侊細

  1. public T orElse(T other) {

  2. return value != ? value : other;

  3. }


  4. public T orElseGet(Supplier<? extends T> other) {

  5. return value != ? value : other.get();

  6. }


  7. public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {

  8. if (value != ) {

  9. return value;

  10. } else {

  11. throw exceptionSupplier.get();

  12. }

  13. }

orElse()鍜宱rElseGet()鏂规硶鏈€鐩磋鐨勫樊寮傛槸褰㈠弬鐨勪笉鍚岋紝鐪嬩笅闈竴娈典唬鐮侊細

  1. //娴嬭瘯璇彞

  2. Optional<Chestnut> opChest = Optional.ofable(new Chestnut("妗愭煆鏉挎牀"));

  3. //Optional<Chestnut> opChest=Optional.empty();

  4. opChest.orElse(print("orELse"));

  5. opChest.orElseGet(()->print("orElseGet"));

  6. //璋冪敤鏂规硶

  7. private static Chestnut print(String method){

  8. System.out.println("鐕曞北鏉挎牀鏈€濂藉悆----"+method);

  9. return new Chestnut("鐕曞北鏉挎牀");

  10. }

绗竴娆★紝new鍑轰竴涓€滄鏌忔澘鏍椻€濈殑Optional锛屽垎鍒皟鐢╫rElse()鍜宱rElseGet()鏂规硶锛岀粨鏋滃嚭鐜颁簡涓よ鐨勨€滅嚂灞辨澘鏍楁渶濂藉悆鈥濈殑杈撳嚭锛屽洜涓轰袱涓柟娉曞湪value涓嶄负鏃堕兘浼氭墽琛屽舰鍙備腑鐨勬柟娉曪紱
绗簩娆★紝閫氳繃empty()鏂规硶鑾峰緱涓€涓┖鏍楀瓙鐨凮ptional锛屽啀璋冪敤orElse()鍜宱rElseGet()鏂规硶锛岀粨鏋滃眳鐒惰繕鍑虹幇浜嗕竴琛屸€滅嚂灞辨澘鏍楁渶濂藉悆鈥濈殑杈撳嚭銆?/p>

  1. 绗竴娆¤緭鍑猴細

  2. 鐕曞北鏉挎牀鏈€濂藉悆----orELse

  3. 鐕曞北鏉挎牀鏈€濂藉悆----orElseGet

  4. 绗簩娆¤緭鍑猴細

  5. 鐕曞北鏉挎牀鏈€濂藉悆----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>

3锛夊叾浠栨柟娉曠殑瀵规瘮

a銆乵ap涓巉ilterMap
鍏堜笂婧愮爜锛?/p>

  1. public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {

  2. Objects.requireNon(mapper);

  3. if (!isPresent())

  4. return empty();

  5. else {

  6. return Optional.ofable(mapper.apply(value));

  7. }

  8. }


  9. public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {

  10. Objects.requireNon(mapper);

  11. if (!isPresent())

  12. return empty();

  13. else {

  14. return Objects.requireNon(mapper.apply(value));

  15. }

  16. }

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()鐨勬敼杩涙柟娉曞嚭鐜扮殑銆傚厛鐪嬫簮鐮侊細

  1. public void ifPresent(Consumer<? super T> action) {

  2. if (value != ) {

  3. action.accept(value);

  4. }

  5. }

  6. public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {

  7. if (value != ) {

  8. action.accept(value);

  9. } else {

  10. emptyAction.run();

  11. }

  12. }

浠庢簮鐮佷腑鍙互鐪嬪嚭锛宨fPresentOrElse()鍙傛暟澧炲姞浜嗕竴涓猂unnable绫诲瀷鐨勫嚱鏁癳mptyAction锛屽湪value !=鏃讹紝閮芥縺娲讳簡action.accept()鏂规硶銆傚彧鏄綋value==鏃讹紝ifPresentOrElse()鏂规硶杩樹細璋冪敤emptyAction.run()鏂规硶銆傛墍浠ユ€荤殑鏉ヨ锛宩dk1.9鍔犲叆ifPresentOrElse()鏂规硶锛屾槸浣滀负ifPreset鍦╥f-else棰嗗煙鐨勮ˉ鍏呭嚭鐜扮殑銆?/p>

c銆乷r涓巓rElse
鍚屾牱浣滀负鏀硅繘鐨刼r()鏂规硶涔熸槸涓轰簡瑙e喅orElse绯诲垪鏂规硶鐨勨€滃皬缂虹偣鈥濆嚭鐜扮殑锛屽厛鐪嬫簮鐮侊細

  1. public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {

  2. Objects.requireNon(supplier);

  3. if (isPresent()) {

  4. return this;

  5. } else {

  6. @SuppressWarnings("unchecked")

  7. Optional<T> r = (Optional<T>) supplier.get();

  8. return Objects.requireNon(r);

  9. }

  10. }

  11. public T orElse(T other) {

  12. return value != ? value : other;

  13. }

  14. public T orElseGet(Supplier<? extends T> supplier) {

  15. return value != ? value : supplier.get();

  16. }

or()鏂规硶鍦ㄧ鍚嶅舰寮忎笂鏇存帴杩憃rElseGet()锛屽嵆褰㈠弬閮芥槸Supplier绫诲瀷鐨勫嚱鏁帮紝浣嗘槸涓庡叾涓嶅悓鐨勬槸锛宱r()鏂规硶鍦ㄥ舰鍙備腑锛屾寚瀹氫簡Supplier杩斿洖鐨勭被鍨嬪繀椤讳负Optional绫诲瀷锛屼笖value鐨勭被鍨嬪繀椤讳负T鎴栬€匱鐨勫瓙绫汇€俹rElse绯诲垪鐨勬柟娉曪紝鏇村儚鏄竴绉嶆秷璐圭殑鏂规硶锛屼粠涓€涓狾ptional鐨勫疄渚嬩腑鈥滃彇鍑衡€渧alue鐨勫€艰繘鍏ヤ笅涓€姝ユ搷浣滐紝鑰宱r()鏂规硶鍒欏儚鏄缓閫犺€呮ā寮忥紝瀵箆alue鏈変竴瀹氱殑鎿嶄綔涔嬪悗锛岄噸鏂板悙鍑虹殑杩樻槸Optional绫诲瀷鐨勬暟鎹紝鎵€浠ヤ娇鐢ㄦ椂鍙互涓茶仈鍦ㄤ竴璧凤紝鍚庝竴涓猳r澶勭悊鍓嶄竴涓猳r鍚愬嚭鐨凮ptional銆?/p>

4锛夆€滃嵄闄┾€濇柟娉曠殑瀵规瘮

杩欓噷鎸囩殑鈥滃嵄闄┾€濇寚鐨勬槸浼氭姏鍑哄紓甯革紝姣曠珶寮曡繘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>

4銆佽鐢ㄥ舰寮忎笌Best practice

1锛夎鐢ㄥ舰寮?/h3>

a銆佸垵濮嬪寲涓?/strong>
绗竴绉嶈鐢ㄥ舰寮忔槸缁橭ptional绫诲瀷鐨勫彉閲忓垵濮嬪寲鐨勬椂鍊?Optional绫诲瀷鍙橀噺鏄粯璁や笉涓虹┖鐨勶紝鎵€浠ュ湪鍙栨柟娉曟墽琛岀殑鏃跺€欐墠鍙互鑲嗘棤蹇屾儺鈥濈偣鈥濆嚭鍘伙紝濡傛灉鍦ㄥ垵濮嬪寲鐨勬椂鍊欏嚭鐜帮細

  1. Optional<Chestnut> chest = ;

骞朵笖涓嶅強鏃朵负chest璧嬪€硷紝鍒欒繕鏄鏄撳嚭鐜癗PE锛屾纭殑鍒濆鍖栨柟寮忓簲璇ユ槸锛?/p>

  1. Optional<Chestnut> chest = Optional.empty();

b銆佺畝鍗曞垽绌?/strong>
绗簩绉嶆瘮杈冨父瑙佺殑璇敤褰㈠紡搴旇鏄娇鐢╥sPresent()鍋氱畝鍗曞垽绌恒€傚師鏈殑浠g爜濡備笅锛?/p>

  1. public String getName(Chestnut chestnut){

  2. if(chestnut == ){

  3. return "鏍楀瓙涓嶅瓨鍦?;

  4. }else return chestnut.name();

  5. }

浠g爜涓紝閫氳繃妫€鏌hestnut==鏉ュ鐞嗕负绌烘椂鐨勬儏鍐碉紝绠€鍗曚娇鐢╥sPresent()鏂规硶鍒ょ┖鐨勪唬鐮佸涓嬶細

  1. public String getName(Chestnut chestnut){

  2. Optional<Chestnut> opChest = Optional.ofable(chestnut);

  3. if(!opChest.isPresent()){

  4. return "鏍楀瓙涓嶅瓨鍦?;

  5. }else return opChest.getname();

  6. }

閰卞┒鍎垮苟娌℃湁澶ぇ宸埆锛屾墍浠ュ湪浣跨敤Optional鏃讹紝棣栧厛搴旈伩鍏嶄娇鐢?Optional.isPresent() 鏉ユ鏌ュ疄渚嬫槸鍚﹀瓨鍦紝鍥犱负杩欑鏂瑰紡鍜?!=obj 娌℃湁鍖哄埆涔熸病浠€涔堟剰涔夈€?/p>

c銆佺畝鍗昰et
绗笁绉嶆瘮杈冨父瑙佺殑璇敤褰㈠紡鏄娇鐢∣ptional.get()鏂瑰紡鏉ヨ幏鍙朞ptional涓璿alue鐨勫€硷紝get()鏂规硶涓value==鐨勬儏鍐垫湁鎶涘嚭寮傚父锛屾墍浠ュ簲璇ュ湪鍋氬畬闈炵┖鏍¢獙涔嬪悗鍐嶄粠get鍙栧€硷紝鎴栬€呭崄鍒嗙‘瀹歷alue涓€瀹氫笉涓虹┖锛屽惁鍒欎細鍑虹幇NoSuchElementException鐨勫紓甯搞€傜浉瀵圭殑锛屽鏋滀笉鏄緢纭俊锛屽垯浣跨敤orElse()锛宱rElseGet()锛宱rElseThrow()鑾峰緱浣犵殑缁撴灉浼氭洿鍔犲悎閫傘€?/p>

d銆佷綔涓哄睘鎬у瓧娈靛拰鏂规硶鍙傛暟
绗洓绉嶈鐢ㄥ舰寮忓湪鍒濆Optional鐨勬椂鍊欏鏄撶鍒帮紝褰撴寚瀹氭煇涓被涓殑灞炴€э紝鎴栬€呮柟娉曠殑鍙傛暟涓篛ptional鐨勬椂鍊欙紝idea浼氱粰鍑哄涓嬫彁绀猴細

Reports any uses of java.util.Optional, java.util.OptionalDouble, java.util.OptionalInt, java.util.OptionalLong or com.google.common.base.Optional as the type for a field or parameter. Optional was designed to provide a limited mechanism for library method return types where there needed to be a clear way to represent 鈥渘o result鈥? Using a field with type java.util.Optional is also problematic if the class needs to be Serializable, which java.util.Optional is not.

澶ф剰鏄笉寤鸿濡傛浣跨敤Optional銆傜涓€锛屼笉寤鸿浣跨敤Optional浣滀负瀛楁鎴栧弬鏁帮紝鍏惰璁℃槸涓哄簱鏂规硶杩斿洖绫诲瀷鎻愪緵涓€绉嶆湁闄愮殑鏈哄埗锛岃€岃繖绉嶆満鍒跺彲浠ユ竻鏅扮殑琛ㄧず鈥滄病鏈夌粨鏋溾€濈殑璇箟锛涚浜岋紝Optional娌℃湁瀹炵幇Serilazable锛屾槸涓嶅彲琚簭鍒楀寲鐨勩€?br style="box-sizing: border-box;">杩欑璇敤鏂规硶姣旇緝鏄庢樉锛屽鐜板拰閬垮厤涔熸瘮杈冪畝鍗曘€備絾绗旇€呰繕鎯冲氨杩欎袱涓缓璁殑鍘熷洜鍋氳繘涓€姝ョ殑鎺㈢┒锛屾墍浠ユ煡闃呬簡涓€浜涜祫鏂欙紝澶т綋鐨勫師鍥犲涓嬶細
绗竴涓師鍥狅紝涓轰粈涔堜笉閫傚悎鍋氬睘鎬у瓧娈靛拰鏂规硶鍙傛暟锛熺洿鐧界殑璇达紝灏辨槸楹荤儲銆備负浜嗗紩鍏ptional锛屽嵈闇€瑕佸姞鍏ュ娈垫牱鏉夸唬鐮侊紝姣斿鍒ょ┖鎿嶄綔銆備娇寰楀湪涓嶅悎閫傜殑浣嶇疆浣跨敤Optional涓嶄粎娌℃湁缁欐垜浠甫鏉ヤ究鍒╋紝鍙嶈€岀害鏉熶簡鍐欎唬鐮佺殑閫昏緫銆?br style="box-sizing: border-box;">鍐欎互涓嬪煙妯″瀷浠g爜

  1. public class Chestnut {

  2. private String firstName;

  3. private Optional<String> midName = Optional.empty();

  4. private String lastName;

  5. public void setMidName(Optional<String> midName) {

  6. this.midName = midName;

  7. }

  8. public String getFullName() {

  9. String fullName = firstName;

  10. if(midName != ) {

  11. if(midName.isPresent()){

  12. fullName = fullName.concat("." + midName.get());

  13. }

  14. return fullName.concat("." + lastName);

  15. }

  16. }

  17. }

鍙鍦╯etter鏂规硶涓病鏈夊褰㈠弬鍋氱浉搴旂殑鏍¢獙锛岄偅涔堝垯闇€瑕佸湪浣跨敤鐨刧etFullName()鏂规硶涓紝澧炲姞瀵瑰睘鎬idName鐨勫垽绌烘搷浣滐紝鍥犱负瀹屽叏鍙兘閫氳繃setter鏂规硶浣垮緱灞炴€т负銆傚鏋滄妸鍒ょ┖绉诲埌setter鏂规硶涓紝涔熷苟娌℃湁鍑忓皯鍒ょ┖锛屼娇寰楀钩鐧芥尋杩涗簡涓€娈垫牱鏉夸唬鐮併€傚彟澶栧湪浼犲叆鏂规硶鏃讹紝涔熼渶瑕佸鍘熸湰鐨剉alue鍖呰涓€灞傚悗鍐嶄紶鍏ワ紝浣垮緱浠g爜鏄惧緱绱禈浜嗭紝濡備笅锛?/p>

  1. chest.setMidName(Optional.empty());

  2. chest.setMidName(Optional.of("闃挎牀"));

鍦ㄥ睘鎬т笉涓篛ptional鐨勬椂鍊欙紝濡傛灉缁欏睘鎬ц祴鍊硷紝闇€瑕佷娇鐢ㄢ€滄秷璐光€濇搷浣滐紝姣斿orElse()锛屽彇鍑哄€煎啀璧嬬粰灞炴€э紝鐩告瘮鐩存帴浼犲叆String绫诲瀷鐨勫€间綔涓哄瓧娈靛拰褰㈠弬鍙互鍑忓皯杩欎簺姝ラ锛屽悗鑰呭弽鑰屾洿鍔犲悎閫傘€?/p>

绗簩涓師鍥狅紝涓轰粈涔堟病鏈夊疄鐜板簭鍒楀寲锛熺浉鍏冲彲浠ュ弬瑙丣ava Lamda鐨勪笓瀹剁粍璁ㄨ銆?br style="box-sizing: border-box;">
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>

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:
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

瀹炶返涓父甯哥粍鍚堜娇鐢ㄤ互涓婂悇绉嶆柟娉曪紝涓斿緢澶氭柟娉曞父涓嶭ambda琛ㄨ揪寮忕粨鍚堬紝鑾峰彇鎯宠鐨勭粨鏋滐紝杩欓噷鍒楀嚭涓や釜甯歌鐨勪娇鐢ㄦ柟寮忥紝鍊肩被鍨嬭浆鎹㈠拰闆嗗悎鍏冪礌杩囨护銆?/p>

a銆佺ず渚嬩竴

  1. Chestnut chestnut = new Chestnut("閿ユ牀鏉挎牀");

  2. if(chestnut != ){

  3. String chestName = chestnut.getName();

  4. if(chestName != ){

  5. return chestName.concat("濂藉ソ鍚冿紒");

  6. }

  7. }else{

  8. return ;

  9. }

鍙互绠€鍖栨垚锛?/p>

  1. Chestnut chestnut = new Chestnut("閿ユ牀鏉挎牀");

  2. return Optional.ofable(chestnut)

  3. .map(Chestnut::getName)

  4. .map(name->name.concat("濂藉ソ鍚冿紒"))

  5. .orElse();

b銆佺ず渚嬩簩

  1. public static void main(String[] args) {

  2. // 鍒涘缓涓€涓牀瀛愰泦鍚?/span>

  3. List<Chestnut> chestList = new ArrayList<>();

  4. // 鍒涘缓鍑犱釜鏍楀瓙

  5. Chestnut chest1 = new Chestnut("abc");

  6. Chestnut chest2 = new Chestnut("efg");

  7. Chestnut chest3 = ;

  8. // 灏嗘牀瀛愬姞鍏ラ泦鍚?/span>

  9. chestList.add(chest1);

  10. chestList.add(chest2);

  11. chestList.add(chest3);

  12. // 鍒涘缓鐢ㄤ簬瀛樺偍鏍楀瓙鍚嶇殑闆嗗悎

  13. List<String> nameList = new ArrayList();

  14. // 寰幆鏍楀瓙鍒楄〃鑾峰彇鏍楀瓙淇℃伅锛屽€艰幏鍙栦笉涓虹┖涓旀牀瀛愬悕浠モ€榓鈥欏紑澶?/span>

  15. // 濡傛灉涓嶇鍚堟潯浠跺氨璁剧疆榛樿鍊硷紝鏈€鍚庡皢绗﹀悎鏉′欢鐨勬牀瀛愬悕鍔犲叆鏍楀瓙鍚嶉泦鍚?/span>

  16. for (Chestnut chest : chestList) {

  17. nameList.add(Optional.ofable(chest)

  18. .map(Chestnut::getName)

  19. .filter(value -> value.startsWith("a"))

  20. .orElse("鏈~鍐?));

  21. }

  22. // 杈撳嚭鏍楀瓙鍚嶉泦鍚堜腑鐨勫€?/span>

  23. System.out.println("閫氳繃 Optional 杩囨护鐨勯泦鍚堣緭鍑猴細");

  24. nameList.stream().forEach(System.out::println);

  25. }

5銆佹€荤粨

鏈枃棣栧厛锛屼粠鎵€瑙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>

6銆佸弬鑰?/h2>

[1] https://mp.weixin.qq.com/s/q_WmD3oMvgPhakiPLAq-CQ 鏉ユ簮:wechat
[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 鏉ユ簮:鐭ヤ箮


  • 璋堣皥Tomcat杩炴帴鍣?/span>

  • 鐖卞鑹哄熀浜嶴pringCloud鐨勯煣鎬ц兘鍔涘缓璁?/span>

  • vivo缁熶竴鍛婅骞冲彴寤鸿涓庡疄璺?/span>

  • 缇庡浘Android缂栬瘧閫熷害浼樺寲瀹炶返鎸囧崡

  • 鍩轰簬etcd瀹炵幇澶ц妯℃湇鍔℃不鐞嗗簲鐢ㄥ疄鎴?/span>


鎶€鏈師鍒涘強鏋舵瀯瀹炶返鏂囩珷锛屾杩庨€氳繃鍏紬鍙疯彍鍗曘€岃仈绯绘垜浠€嶈繘琛屾姇绋裤€?/span>


楂樺彲鐢ㄦ灦鏋?/strong>
鏀瑰彉浜掕仈缃戠殑鏋勫缓鏂瑰紡

楦熷涔犺锛氱鍥涘崄澶?/h1>

鍓嶈█

鉂?/span>

Hello锛佸皬浼欎即锛?/p>

闈炲父鎰熻阿鎮ㄩ槄璇绘捣杞扮殑鏂囩珷锛屽€樿嫢鏂囦腑鏈夐敊璇殑鍦版柟锛屾杩庢偍鎸囧嚭锝?/p>

鑷垜浠嬬粛 喱?喋娽禃藡)喋?/p>

鏄电О锛氭捣杞?/p>

鏍囩锛氱▼搴忕尶锝淐++閫夋墜锝滃鐢?/p>

绠€浠嬶細鍥燙璇█缁撹瘑缂栫▼锛岄殢鍚庤浆鍏ヨ绠楁満涓撲笟锛屾湁骞告嬁杩囦竴浜涘浗濂栥€佺渷濂?..宸蹭繚鐮斻€傜洰鍓嶆鍦ㄥ涔燙++/Linux/Python

瀛︿範缁忛獙锛氭墡瀹炲熀纭€ + 澶氬仛绗旇 + 澶氭暡浠g爜 + 澶氭€濊€?+ 瀛﹀ソ鑻辫锛?/p>

鏁堟灉灞曠ず

鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>

Demo浠g爜

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)
  }
}

鍘熺悊璇﹁В

姝ラ1

浣跨敤span鏍囩浣滀负绠熬锛岃缃负

  • 瀹藉害銆侀珮搴﹀潎涓?6px
  • 涓婅竟妗嗭細10px 绾㈣壊 dashed锛堣櫄绾匡級
  • 涓嬭竟妗嗭細10px 閫忔槑 solid锛堝疄绾匡級
  • 宸﹁竟妗嗭細10px 绾㈣壊 dotted锛堢偣鐘讹級
  • 鍙宠竟妗嗭細10px 绾㈣壊 solid锛堝疄绾匡級
 width : 96px;
  height: 96px;
  border: 10px red;
  border-style: dashed solid  solid dotted;
  border-bottom-color: transparent; 

鏁堟灉鍥惧涓?/span>

鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>

姝ラ2

span鏍囩鍦嗚鍖?/span>

border-radius: 50%;

鏁堟灉鍥惧涓?/span>

鍦ㄨ繖閲屾彃鍏ュ浘鐗囨弿杩?/span>

姝ラ3

浣跨敤span::after浼被鍏冪礌 浣滀负绠ご

璁剧疆涓?/span>

  • 缁濆瀹氫綅
  • 杈规锛?0px solid锛屽彸杈规涓虹孩鑹诧紝涓?涓?宸﹁竟妗嗕负閫忔槑
  • 鏃嬭浆-45搴?/span>
  position: absolute;
  border: 20px solid transparent;
  border-right-color: red;
  transform: rotate(-45deg);

鏁堟灉鍥惧涓?/span>

姝ラ4

璁剧疆span::after鐨勪綅缃?/span>

娉細

  • 杩欓噷绉诲姩浣嶇疆鏃跺€欏氨闇€瑕佷竴鐐圭偣绉诲姩浜?/span>
  • 纭繚绠ご鍜岀灏惧彲浠ュ緢濂界殑閲嶅悎
  • 杩欓噷鑲畾鏄彲浠ョ敤鏁板鍏紡璁$畻鍑烘潵鐨勶紝杩欓噷绋嶅井闇€瑕佺偣鏃堕棿锛屼箣鍚庢湁绌哄啀鏇存柊鏇翠负涓€鑸儏鍐垫椂闇€瑕佺Щ鍔ㄧ殑璺濈鍏紡鍚?/span>
/*杩欓噷绠ご闇€瑕佺Щ鍔ㄧ殑璺濈*/
  left: 51px;
  top: 79px;

鏁堟灉鍥惧涓?/span>

姝ラ5

涓簊pan娣诲姞鍔ㄧ敾

  • 椤烘椂閽堟棆杞紙0-360搴︼級 2s 鏃犻檺寰幆
 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>