面試官寫了個雙冒號::問我這是什么語法?Java中有這玩意?
來源:suo.im/6vK9mY
一:簡潔 二:方法引用 三:Optional 可選值
一:簡潔
方法引用分為三種,方法引用通過一對雙冒號:: 來表示,方法引用是一種函數(shù)式接口的另一種書寫方式
靜態(tài)方法引用,通過類名::靜態(tài)方法名, 如 Integer::parseInt 實(shí)例方法引用,通過實(shí)例對象::實(shí)例方法,如 str::substring 構(gòu)造方法引用,通過類名::new, 如 User::new
二:方法引用
public?final?class?Integer?{
????public?static?int?parseInt(String?s)?throws?NumberFormatException?{
????????return?parseInt(s,10);
????}
}
通過方法引用,可以將方法的引用賦值給一個變量,通過賦值給Function,說明方法引用也是一種函數(shù)式接口的書寫方式,Lambda表達(dá)式也是一種函數(shù)式接口,Lambda表達(dá)式一般用于自己提供方法體,而方法引用一般直接引用現(xiàn)成的方法。
public?class?User?{
????private?String?username;
????private?Integer?age;
????public?User()?{
????}
????public?User(String?username,?Integer?age)?{
????????this.username?=?username;
????????this.age?=?age;
????}
????@Override
????public?String?toString()?{
????????return?"User{"?+
????????????????"username='"?+?username?+?'\''?+
????????????????",?age="?+?age?+
????????????????'}';
????}
????//?Getter&Setter
}
public?static?void?main(String[]?args)?{
????//?使用雙冒號::來構(gòu)造靜態(tài)函數(shù)引用
????Function?fun?=?Integer::parseInt;
????Integer?value?=?fun.apply("123");
????System.out.println(value);
????//?使用雙冒號::來構(gòu)造非靜態(tài)函數(shù)引用
????String?content?=?"Hello?JDK8";
????Function?func?=?content::substring;
????String?result?=?func.apply(1);
????System.out.println(result);
????//?構(gòu)造函數(shù)引用
????BiFunction?biFunction?=?User::new;
????User?user?=?biFunction.apply("mengday",?28);
????System.out.println(user.toString());
????//?函數(shù)引用也是一種函數(shù)式接口,所以也可以將函數(shù)引用作為方法的參數(shù)
????sayHello(String::toUpperCase,?"hello");
}
//?方法有兩個參數(shù),一個是
private?static?void?sayHello(Function?func,?String?parameter) {
????String?result?=?func.apply(parameter);
????System.out.println(result);
}
三:Optional 可選值
在Google Guava 中就有Optional,在Swift語言中也有這樣類似的語法,在Swift中將可選值作為一種數(shù)據(jù)類型,地位和基本類型平齊平做,地位非常高。
package?java.util;
import?java.util.function.Consumer;
import?java.util.function.Function;
import?java.util.function.Predicate;
import?java.util.function.Supplier;
/**
?*?@since?1.8
?*/
public?final?class?Optional<T>?{
????private?static?final?Optional>?EMPTY?=?new?Optional<>();
????private?final?T?value;
????private?Optional()?{
????????this.value?=?null;
????}
????//?返回一個空的?Optional實(shí)例
????public?static?Optional?empty()? {
????????@SuppressWarnings("unchecked")
????????Optional?t?=?(Optional)?EMPTY;
????????return?t;
????}
????private?Optional(T?value)?{
????????this.value?=?Objects.requireNonNull(value);
????}
????//?返回具有?Optional的當(dāng)前非空值的Optional
????public?static??Optional?of(T?value)? {
????????return?new?Optional<>(value);
????}
????//?返回一個?Optional指定值的Optional,如果非空,則返回一個空的?Optional
????public?static??Optional?ofNullable(T?value)? {
????????return?value?==?null???empty()?:?of(value);
????}
????//?如果Optional中有一個值,返回值,否則拋出 NoSuchElementException 。
????public?T?get()?{
????????if?(value?==?null)?{
????????????throw?new?NoSuchElementException("No?value?present");
????????}
????????return?value;
????}
????//?返回true如果存在值,否則為?false
????public?boolean?isPresent()?{
????????return?value?!=?null;
????}
????//?如果存在值,則使用該值調(diào)用指定的消費(fèi)者,否則不執(zhí)行任何操作。
????public?void?ifPresent(Consumer?super?T>?consumer)?{
????????if?(value?!=?null)
????????????consumer.accept(value);
????}
????//?如果一個值存在,并且該值給定的謂詞相匹配時,返回一個?Optional描述的值,否則返回一個空的?Optional
????public?Optional?filter(Predicate?super?T>?predicate)? {
????????Objects.requireNonNull(predicate);
????????if?(!isPresent())
????????????return?this;
????????else
????????????return?predicate.test(value)???this?:?empty();
????}
????//?如果存在一個值,則應(yīng)用提供的映射函數(shù),如果結(jié)果不為空,則返回一個 Optional結(jié)果的 Optional 。
????public?Optional?map(Function?super?T,???extends?U>?mapper)?{
????????Objects.requireNonNull(mapper);
????????if?(!isPresent())
????????????return?empty();
????????else?{
????????????return?Optional.ofNullable(mapper.apply(value));
????????}
????}
????//?如果一個值存在,應(yīng)用提供的 Optional映射函數(shù)給它,返回該結(jié)果,否則返回一個空的 Optional 。
????public?Optional?flatMap(Function?super?T,?Optional>?mapper)?{
????????Objects.requireNonNull(mapper);
????????if?(!isPresent())
????????????return?empty();
????????else?{
????????????return?Objects.requireNonNull(mapper.apply(value));
????????}
????}
????//?如果值存在,就返回值,不存在就返回指定的其他值
????public?T?orElse(T?other)?{
????????return?value?!=?null???value?:?other;
????}
????public?T?orElseGet(Supplier?extends?T>?other)?{
????????return?value?!=?null???value?:?other.get();
????}
????public??T?orElseThrow(Supplier?extends?X>?exceptionSupplier)?throws?X?{
????????if?(value?!=?null)?{
????????????return?value;
????????}?else?{
????????????throw?exceptionSupplier.get();
????????}
????}
}
關(guān)于of方法,現(xiàn)在好像很流行,就是提供一個static方法,方法名稱叫of,方法的返回值返回當(dāng)前類,并且把構(gòu)造函數(shù)設(shè)置為私有private,用靜態(tài)of方法來代替構(gòu)造函數(shù)。
public?class?User?{
????private?String?username;
????private?Integer?age;
????private?User()?{
????}
????public?static?User?of()?{
????????return?new?User();
????}
????private?User(String?username,?Integer?age)?{
????????this.username?=?username;
????????this.age?=?age;
????}
????public?static?User?of(String?username,?Integer?age)?{
????????return?new?User(username,?age);
????}
}
Main
public?static?void?main(String[]?args)?{
????//?Optional類已經(jīng)成為Java?8類庫的一部分,在Guava中早就有了,可能Oracle是直接拿來使用了
????//?Optional用來解決空指針異常,使代碼更加嚴(yán)謹(jǐn),防止因?yàn)榭罩羔楴ullPointerException對代碼造成影響
????String?msg?=?"hello";
????Optional?optional?=?Optional.of(msg);
????//?判斷是否有值,不為空
????boolean?present?=?optional.isPresent();
????//?如果有值,則返回值,如果等于空則拋異常
????String?value?=?optional.get();
????//?如果為空,返回else指定的值
????String?hi?=?optional.orElse("hi");
????//?如果值不為空,就執(zhí)行Lambda表達(dá)式
????optional.ifPresent(opt?->?System.out.println(opt));
}
推薦閱讀
程序員內(nèi)推群!北京!上海!廣州!深圳!杭州!鄭州!武漢!南京!西安!
推薦一個開源的vue+Element UI前后端分離后臺管理系統(tǒng)實(shí)戰(zhàn)!
一套簡單通用的Java后臺管理系統(tǒng)
招聘需
評論
圖片
表情
