日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数字类 default 0和 default 0_04Optional类和接口中的default、static方法

發布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数字类 default 0和 default 0_04Optional类和接口中的default、static方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章,介紹Jave8的 Optional 類和接口的 default、static 方法。

1、Optional類

Optional:Java8 java.util包中提供的一個可以包含或者不包含非null值的容器對象。
通過 Optional 我們不用顯式進行空值檢測 ( if( T == null ) )也很好的解決空指針異常

1.1 Optional API

Optional 方法說明
static?Optional?empty()返回一個空Optional(值為null)
boolean equals(Object obj)指示給定的對象是否 equals 此Optional的value
Optional?filter(Predicate super?predicate)如果 Optional 的值存在而且匹配給定的 predicate(斷定型函數式接口),返回當前Optional,否則返回一個空Optional(值為null)
Optional flatMap(Function super T,Optional> mapper)如果 Optional 的值存在,應用提供的映射方法并返回結果 Optional,否則返回一個空的Optional
T get()如果此 Optional 存在值,則返回值,否則拋出NoSuchElementException
int hashCode()返回當前值的哈希碼值(如果有),如果沒有值,則返回0。
void ifPresent(Consumer super T> consumer)如果存在值,對該值應用指定的 Consumer(消費型函數式接口),否則不執行任何操作。
boolean isPresent()如果存在值,返回true,否則返回false
Optional map(Function super T,? extends U> mapper)如果值存在,對該值應用給定的映射方法,如果是非null的結果,返回一個描述該值的 optional,否則返回一個空Optional(值為null)
static?Optional?of(T value)通過給定的value,返回一個值為給定value的Optional實例,value不能為null,若value為null,則拋出NullPointerException
static?Optional?ofNullable(T value)通過給定的value,返回一個值為給定value的Optional實例,value可為null
T orElse(T other)如果此Optional的value不為null,則返回value,否則返回給定的other對象
T orElseGet(Supplier extends T> other)如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier(供給型函數式接口)返回一個T類型的對象
T orElseThrow(Supplier extends X> exceptionSupplier)如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier創建一個Throwable
String toString()返回非空字符串表示此Optional,適用于調試。

項目中常用的實例方法,用于解決空指針異常

  • isPresent()方法,如果存在值,將返回true,否則返回false。

  • orElse(T other)方法,如果存在值,則返回當前Optional的value,否則返回 other

  • ifPresent(Consumer super T> consumer),如果存在值,對該值應用指定的 Consumer,執行代碼塊,否則不做任何操作

1.2 Optional 源碼

public final class Optional<T> {
/**
* empty()方法的公共實例
*/
private static final Optional> EMPTY = new Optional<>();

/**
* Optional的值,類型為T
*/
private final T value;

/**
* 私有構造器
*/
private Optional() {
this.value = null;
}

/**
* 返回一個空Optional(值為null)
*/
public static Optionalempty() {@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;return t;
}/**
* value為入參的構造器,value不能為null,若value為null,則拋出NullPointerException
*/private Optional(T value) {this.value = Objects.requireNonNull(value);
}/**
* 通過給定的value,返回一個值為給定value的Optional實例,value不能為null,若value為null,則拋出NullPointerException
*/public static Optionalof(T value) {return new Optional<>(value);
}/**
* 通過給定的value,返回一個值為給定value的Optional實例,value可為null,若value為null,則返回 EMPTY
*/public static OptionalofNullable(T value) {return value == null ? empty() : of(value);
}/**
* 如果此 Optional 存在值,則返回值,否則拋出NoSuchElementException
*/public T get() {if (value == null) {throw new NoSuchElementException("No value present");
}return value;
}/**
* 如果存在值 value!=null,返回true,否則返回false
*/public boolean isPresent() {return value != null;
}/**
* 如果存在值,對該值應用指定的 Consumer(消費型函數式接口),否則不執行任何操作。
*/public void ifPresent(Consumer super T> consumer) {if (value != null)
consumer.accept(value);
}/**
* 如果 Optional 的值存在而且匹配給定的 predicate(斷定型函數式接口),返回當前Optional,否則返回一個空Optional(值為null)
*/public Optionalfilter(Predicate super T> predicate) {
Objects.requireNonNull(predicate);if (!isPresent())return this;elsereturn predicate.test(value) ? this : empty();
}/**
* 如果值存在,對該值應用給定的映射方法,如果是非null的結果,返回一個描述該值的 optional,否則返回一個空Optional(值為null)
*/public Optional map(Function super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);if (!isPresent())return empty();else {return Optional.ofNullable(mapper.apply(value));
}
}/**
* 如果 Optional 的值存在,應用提供的映射方法并返回結果Optional,否則返回一個空的Optional
*/public Optional flatMap(Function super T, Optional> mapper) {
Objects.requireNonNull(mapper);if (!isPresent())return empty();else {return Objects.requireNonNull(mapper.apply(value));
}
}/**
* 如果此Optional的value不為null,則返回value,否則返回給定的other對象
*/public T orElse(T other) {return value != null ? value : other;
}/**
* 如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier(供給型函數式接口)返回一個T類型的對象
*/public T orElseGet(Supplier extends T> other) {return value != null ? value : other.get();
}/**
* 如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier創建一個Throwable
*/public T orElseThrow(Supplier extends X> exceptionSupplier) throws X {if (value != null) {return value;
} else {throw exceptionSupplier.get();
}
}/**
* 指示給定的對象是否 equals 此Optional的value
*/@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;
}if (!(obj instanceof Optional)) {return false;
}
Optional> other = (Optional>) obj;return Objects.equals(value, other.value);
}/**
* 返回當前值的哈希碼值(如果有),如果沒有值,則返回0。
*/@Overridepublic int hashCode() {return Objects.hashCode(value);
}/**
* 返回非空字符串表示此Optional,適用于調試。
*/@Overridepublic String toString() {return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
}

1.3 Optional 簡單使用


public class Person {

//姓名
private String name;
//年齡
private long age;

public Person(String name, long age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public long getAge() {
return age;
}

public void setAge(long age) {
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

}


@Test
public void test() {
Person p = new Person("張三", 18);

// 通過給定的value,返回一個值為給定value的Optional實例,若value為null,則拋出NullPointerException
// Optional o = Optional.of(null);
Optional opPerson = Optional.of(p);
System.out.println("of(T value): " + opPerson);// 通過給定的value,返回一個值為給定value的Optional實例,value可為null,若value為null,則返回 Optional.EMPTY
Optional opNull = Optional.ofNullable(null);
System.out.println("ofNullable(T value): " + opNull);// 如果此 Optional 存在值,則返回值,否則拋出NoSuchElementException// Person person = opNull.get();// 拋出NoSuchElementException
Person person = opPerson.get();
System.out.println("T get(): " + person);// 如果存在值 value!=null,返回true,否則返回falseboolean opNullPresent = opNull.isPresent();
System.out.println("opNull persent: " + opNullPresent);if (!opNull.isPresent()) {
System.out.println("opNull 的 value == null");
} else {
System.out.println("opNull 的 value = " + opNull.get());
}boolean opPersonPresent = opPerson.isPresent();
System.out.println("opPerson persent: " + opPersonPresent);// 如果 opPerson 的 value != null,輸出下面語句
opPerson.ifPresent(value -> System.out.println(value.getName() + "的年齡是" + value.getAge()));// 如果 Optional 的值存在而且匹配給定的 predicate(斷定型函數式接口),返回當前Optional,否則返回一個空Optional(值為null)
System.out.println("opNull.filter(): " + opNull.filter(value -> value.getAge() == 18));
System.out.println("opPerson.filter() 匹配age==18: " + opPerson.filter(value -> value.getAge() == 18));
System.out.println("opPerson.filter() 匹配age==19: " + opPerson.filter(value -> value.getAge() == 19));// 如果值存在,對該值應用給定的映射方法,如果是非null的結果,返回一個描述該值的 optional,否則返回一個空Optional(值為null)// Person::getName 方法引用等同于 lambda表達式:value->value.getName()// Function funcGetName = value->value.getName();
Function funcGetName = Person::getName;
Optional opNameofOpNull = opNull.map(funcGetName);
Optional opNameofOpPerson = opPerson.map(funcGetName);
System.out.println("opNull.map(): " + opNameofOpNull);
System.out.println("opPerson.map(): " + opNameofOpPerson);// 如果 Optional 的值存在,應用提供的映射方法并返回結果 Optional,否則返回一個空的Optional
Optional op1 = opNull.flatMap(value -> Optional.of(new Person("李四", 20)));
Optional op2 = opPerson.flatMap(value -> Optional.of(new Person("李四", 20)));
System.out.println("opNull.flatMap(): " + op1);
System.out.println("opPerson.flatMap(): " + op2);// 如果此Optional的value不為null,則返回value,否則返回給定的other對象
Person wangwu = new Person("王五", 25);
System.out.println("opNull.orElse(): " + opNull.orElse(wangwu));
System.out.println("opPerson.orElse(): " + opPerson.orElse(wangwu));// 如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier(供給型函數式接口)返回一個T類型的對象
Supplier supplier = () -> new Person("趙六", 26);
System.out.println("opNull.orElseGet(): " + opNull.orElseGet(supplier));
System.out.println("opPerson.orElseGet(): " + opPerson.orElseGet(supplier));// 如果此Optional的value不為null,則返回value,否則通過調用給定的Supplier創建一個Throwable
Supplier nullPointerExceptionSupplier = () -> new NullPointerException("value is null");
System.out.println("opPerson.orElseThrow(): " + opPerson.orElseThrow(nullPointerExceptionSupplier));
System.out.println("opNull.orElseThrow(): " + opNull.orElseThrow(nullPointerExceptionSupplier));
}

運行結果:

of(T value): Optional[Person{name='張三', age=18}]
ofNullable(T value): Optional.empty
T get(): Person{name='張三', age=18}
opNull persent: false
opNull 的 value == null
opPerson persent: true
張三的年齡是18
opNull.filter(): Optional.empty
opPerson.filter() 匹配age==18: Optional[Person{name='張三', age=18}]
opPerson.filter() 匹配age==19: Optional.empty
opNull.map(): Optional.empty
opPerson.map(): Optional[張三]
opNull.flatMap(): Optional.empty
opPerson.flatMap(): Optional[Person{name='李四', age=20}]
opNull.orElse(): Person{name='王五', age=25}
opPerson.orElse(): Person{name='張三', age=18}
opNull.orElseGet(): Person{name='趙六', age=26}
opPerson.orElseGet(): Person{name='張三', age=18}
opPerson.orElseThrow(): Person{name='張三', age=18}

java.lang.NullPointerException: value is null

at com.xander.java8._optional.OptionalTest.lambda$test$7(OptionalTest.java:83)
at java.util.Optional.orElseThrow(Optional.java:290)
...

2 接口的增強:default 和 static 方法

2.1 default方法

java8中允許接口中包含具有具體實現的方法,用default關鍵字修飾,這類型方法稱為“默認方法”。
不用被default關鍵字嚇到,default?方法也是普通方法,只不過它遵循?"類優先"?原則(下面介紹)

我們看JDK源碼時,可以經??吹?default 方法,如?Consumer類:

@FunctionalInterface
public interface Consumer<T> {

/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);

/**
* 這就是一個default方法
*/
default ConsumerandThen(Consumer super T> after) {
Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };
}
}

default方法的調用遵循?"類優先"?原則

  • 接口中定義了default方法,如果實現類中重寫了該方法,則調用的是實現類中重寫后的方法,如果實現類中沒有重寫default方法,則執行的是接口中定義的default方法。

  • 如果實現類實現了一個接口和繼承了一個父類,接口的默認方法和父類中某一個方法具有相同名稱和參數列表,而且實現類沒有進行該方法的重寫,則使用的是父類的方法。

  • 方法沖突,實現類中實現了兩個接口,這兩個接口中具有相同名稱和參數列表的方法(不管是不是default方法),如果實現類中沒有對default方法進行重寫,則編譯出錯。實現類中必須必須重寫覆蓋該方法來解決沖突。

2.2 default方法簡單使用

public interface DefaultIntf {

/**
* default 方法
*/
default void sayHello() {
System.out.println("DefaultIntf say hello 2 you");
}
}

public interface SayHelloIntf {
/**
* default 方法
*/
default void sayHello() {
System.out.println("SayHelloIntf hello");
}
}

public class Animal {

public void sayHello() {
System.out.println("Animal say hello");
}
}

public class Cat implements DefaultIntf {

@Override
public void sayHello() {
System.out.println("Hello I am Cat sayHello");
}

}

public class Dog implements DefaultIntf {
}

public class Bird extends Animal implements DefaultIntf {
}

public class Fish implements SayHelloIntf, DefaultIntf {

/**
* **方法沖突**,類中實現了兩個接口,這兩個接口中具有相同名稱和參數列表的方法(不管是不是default方法),
* 如類中沒有對default方法進行重寫,則編譯出錯。子類中必須必須覆蓋該方法來解決沖突。
*/
@Override
public void sayHello() {
System.out.println("Hello this is Fish");
}
}

@Test
public void testDefaultMethod() {
DefaultIntf dog = new Dog();
DefaultIntf cat = new Cat();
Bird bird = new Bird();
Fish fish = new Fish();

// 執行默認方法
// 實現類中沒有重寫default方法,執行的是接口中的default
dog.sayHello();
// 實現類中對default進行重寫,則執行的是重寫后的方法
cat.sayHello();
// 如果類實現了一個接口和繼承了一個父類,接口的默認方法和父類中某一個方法具有相同名稱和參數列表,而且子類沒有進行該方法的重寫,則使用的是父類的方法。
bird.sayHello();
// 類中實現了兩個接口,這兩個接口中具有相同名稱和參數列表的方法(不管是不是default方法),子類中必須必須覆蓋該方法,否則編譯異常。
fish.sayHello();
}


運行結果:

DefaultIntf say hello 2 you
Hello I am Cat sayHello
Animal say hello
Hello this is Fish

2.3 項目實戰場景

獲取接口實例的泛型Class

/**
* Description: 接口:包含一個default方法,該接口所有的實例都可以通過該default獲取泛型類型
*
* @author Xander
* datetime: 2020/9/7
*/
public interface GenericIntf<T> {

/**
* 默認方法:獲取泛型T的 Class
*
* @return
*/
default ClassgetGenericClass() {
Type[] types = this.getClass().getGenericInterfaces();
ParameterizedType parameterizedType = (ParameterizedType) types[0];
Class tClass = (Class) parameterizedType.getActualTypeArguments()[0];return tClass;
}
}/**
* Description: GenericIntf的實現類,泛型類型是Double
*
* @author Xander
* datetime: 2020/9/7
*/public class GenericDouble implements GenericIntf<Double> {
}/**
* Description: GenericIntf的實現類,泛型類型是Integer
*
* @author Xander
* datetime: 2020/9/7
*/public class GenericInteger implements GenericIntf<Integer> {
}@Testpublic void testGeneric() {// 獲取 GenericIntf接口實例的 泛型類型
GenericIntf genericInt = new GenericInteger();
GenericIntf genericDouble = new GenericDouble();
Class genericIntClass = genericInt.getGenericClass();//泛型類型是 Integer
Class genericDoubleClass = genericDouble.getGenericClass();//泛型類型是 Double
System.out.println("GenericInteger的泛型類型:" + genericIntClass);
System.out.println("genericDouble的泛型類型:" + genericDoubleClass);
}

運行結果:

GenericInteger 的泛型類型:class java.lang.Integer
GenericDouble 的泛型類型:class java.lang.Double

2.4 static 方法簡單使用

java8允許接口像普通類一樣定義和使用靜態方法。

public interface StaticIntf {

static void printInfo() {
System.out.println("執行接口中的static方法:" + StaticIntf.class);
}
}

@Test
public void test(){
// 執行接口中 static 方法
StaticIntf.printInfo();
}

運行結果:

執行接口中的static方法:interface com.xander.java8._06default_static_method.StaticIntf

結語:?Optional類和接口的default、static可以作為很好的編程手段用來實現業務邏輯,Optional可以優雅地解決空指針異常,而接口的default和static方法,能夠讓我們定義在接口層級公共的方法,希望Java8的這兩個特性能夠幫助到大家。

代碼:
https://github.com/wengxingxia/001java8.git

[慕課手記同步:04-Optional類和接口中的default、static方法]?https://www.imooc.com/article/310370

提示:?根據相關法律法規和平臺規則要求,自2018年2月12日起,新注冊的微信公眾帳號無法再開通留言功能。
有問題或希望交流的朋友,可以到 [慕課手記同步:04-Optional類和接口中的default、static方法]?https://www.imooc.com/article/310370?下評論留言,一起學習進步。


歡迎關注公眾號"黑桃"

總結

以上是生活随笔為你收集整理的数字类 default 0和 default 0_04Optional类和接口中的default、static方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。