中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于Consumer接口、Predicate接口初使用是怎樣的

發布時間:2021-12-20 21:23:44 來源:億速云 閱讀:159 作者:柒染 欄目:開發技術

這篇文章將為大家詳細講解有關基于Consumer接口、Predicate接口初使用是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Consumer 接口

源碼

package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);    
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

從源碼中可以得到,Consumer 接口是函數式接口,并且這個函數式接口的唯一抽象方法是沒有返回值的,也許大家會有疑惑,沒有返回值,那這個接口有什么用呢?當然,這個接口不會給我們返回什么值,但是我們可以用來修改傳遞過來的參數啊,這樣比直接修改又多了什么優點呢?額,自己挖坑?我也說不上來多了什么優點,我還很弱,不過我喜歡這種編程方式。

直接使用 accept()

舉個例子,假如用戶的 name 為 null,那么就可以給他設置一個默認的 name ,想不到好的例子,感覺這個例子不是很合理,但是意思差不多。

User.java:

package entity;
public class User {
    // 用戶默認名字
    public static final String  DEFAULT_NAME = "Kaven";
    // 用戶的年齡
    private int age;
    // 用戶的名字
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

testConsumer.java:

package test;
import entity.User;
import java.util.function.Consumer;
public class testConsumer{
    public static void main(String[] args){
        Consumer<User> consumer = user -> user.setName(User.DEFAULT_NAME);
        User user = new User();
        if(user.getName() == null) consumer.accept(user);
        System.out.println(user.getName());
    }
}

輸出:Kaven

使用 andThen()

從源碼可以得到,this 進行 accept() 后,after 再進行 accept(),相當于進行了兩次 accept() 。

default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }

下面以小學成績單為例,假設小學成績單是由兩門單科成績(語文、數學)和總分組成,當我們需要修改其中一門成績的時候,我們是不是也需要修改總分呢?這是肯定的啊。當然,這個例子也不是很合理。

Grade.java:

package entity;
public class Grade {
    // 語文成績
    private int chinese_language;
    // 英語成績
    private int english;
    // 總分
    private int total_score;
    public Grade(int chinese_language, int english){
        this.chinese_language = chinese_language;
        this.english = english;
        this.total_score = chinese_language + english;
    }
    public int getChinese_language() {
        return chinese_language;
    }
    public void setChinese_language(int chinese_language) {
        this.chinese_language = chinese_language;
    }
    public int getEnglish() {
        return english;
    }
    public void setEnglish(int english) {
        this.english = english;
    }
    public int getTotal_score() {
        return this.total_score;
    }
    public void setTotal_score() {
        this.total_score = this.chinese_language + this.english;
    }
}

testConsumerAndThen.java:

package test;
import entity.Grade;
import java.util.function.Consumer;
public class testConsumerAndThen {
    public static void main(String[] args){
        Consumer<Grade> total_score = grade -> {
            grade.setTotal_score();
        };
        Consumer<Grade> english = grade -> {
            grade.setEnglish(80);
        };
        Grade grade = new Grade(80,70);
        System.out.printf("英語成績為:%d\n",grade.getEnglish());
        System.out.printf("總分為:%d\n",grade.getTotal_score());
        english.andThen(total_score).accept(grade);
        System.out.println("修改英語成績后---------------");
        System.out.printf("英語成績為:%d\n",grade.getEnglish());
        System.out.printf("總分為:%d\n",grade.getTotal_score());
    }
}

輸出:

英語成績為:70
總分為:150
修改英語成績后---------------
英語成績為:80
總分為:160

Predicate 接口

源碼

package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

Predicate 接口也是函數式接口,調用接口的 test 方法會返回一個布爾類型的值,其實從 Predicate 接口的源碼中也可以看出來,這個接口的用處是什么。

以我的理解,是可以用來判斷傳遞過來的參數是否匹配一些條件。

使用 test()

我們還是使用 Consumer 接口的例子,當用戶的 name 為 null 時,給用戶設置默認的 name。

我們可以用 Predicate 接口來判斷用戶的 name 是否為空,可能看起來比直接比較麻煩一點。

testPredicate.java:

package test;
import entity.User;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class testPredicate {
    public static void main(String[] args){
        Consumer<User> consumer = user -> user.setName(User.DEFAULT_NAME);
        Predicate<User> predicate = user -> {
            return user.getName() == null ;
        };
        User user = new User();
        if(predicate.test(user)) consumer.accept(user);
        System.out.println(user.getName());
    }
}

輸出:Kaven

一樣的效果。

使用 negate()

從源碼中可以得到,negate() 是返回一個對 test() 的結果取一次反的 Predicate 實例。

default Predicate<T> negate() {
        return (t) -> !test(t);
}

也可以這樣用,負負得正不是嗎。

if(!predicate.negate().test(user)) consumer.accept(user);

使用 and()

and() 返回一個對兩個 test() 以 && 的方式的 Predicate 實例。

default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
}

在 User.java 里面加一個用戶默認年齡屬性。

 // 用戶默認年齡
    public static final int DEFAULT_AGE = 20;

當用戶年齡不符合情況并且名字為空時,就重新設置用戶的年齡和名字。

testPredicate.java:

package test;
import entity.User;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class testPredicate {
    public static void main(String[] args){
        Consumer<User> consumer = user -> user.setName(User.DEFAULT_NAME);
        Consumer<User> consumer_age = user -> user.setAge(User.DEFAULT_AGE);
        Predicate<User> predicate = user -> {
            return user.getName() == null ;
        };
        Predicate<User> predicate_age = user -> {
            int age = user.getAge();
            return  (age <= 0 || age >=150);
        };
        User user = new User();
        if(predicate.and(predicate_age).test(user)) consumer.andThen(consumer_age).accept(user);
        System.out.println(user.getName());
        System.out.println(user.getAge());
    }
}

輸出:

Kaven
20

Predicate接口還有兩個方法:

  • or()

or() 方法應該很容易理解,or() 返回一個對兩個 test() 以 || 的方式的 Predicate 實例。

default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
}
  • isEqual()

接口的靜態方法,看源碼也很容易理解,生成一個判斷是否與 targetRef equal的 Predicate 實例。targetRef 不為 null 時,如果 targetRef 這個實例的類中沒有重載 Object 類的 equals() 方法或者 targetRef 這個實例本身就是 Object 類的實例,就會使用 Object 類的 equals() 進行判斷,就只會判斷傳遞過來的參數的引用是否與 targetRef 一樣,和 == 相同。

static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
}

從 Object 類的源碼也很容易看出來,equals() 就是直接使用的 == 進行判斷的。

public boolean equals(Object obj) {
     return (this == obj);
}

要想使用自己的 equals() 進行判斷,就在 targetRef 實例的類中重寫 equals() 方法。

比如在 User.java 中重寫 equals():

@Override
    public boolean equals(Object obj) {
        if(obj == null) return false;
        else{
            if(obj instanceof User){
                User user = (User) obj;
                // String 類已經重載了 equals()
                if(this.name.equals((user).name) && this.age == user.age) return true;
                else return false;
            }
            else return false;
        }
    }

使用 or()、isEqual()

package test;
import entity.User;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class testPredicate {
    public static void main(String[] args){
        Consumer<User> consumer = user -> user.setName(User.DEFAULT_NAME);
        Consumer<User> consumer_age = user -> user.setAge(User.DEFAULT_AGE);
        Predicate<User> predicate = user -> {
            return user.getName() == null ;
        };
        Predicate<User> predicate_age = user -> {
            int age = user.getAge();
            return  (age <= 0 || age >=150);
        };
        User user = new User();
        user.setAge(21);
        if(predicate.or(predicate_age).test(user)) consumer.andThen(consumer_age).accept(user);
//        if(predicate.and(predicate_age).test(user)) consumer.andThen(consumer_age).accept(user);
//        if(!predicate.negate().test(user)) consumer.accept(user);
//        if(predicate.test(user)) consumer.accept(user);
        User user_equal = new User(User.DEFAULT_AGE , User.DEFAULT_NAME);
        System.out.println(Predicate.isEqual(user).test(user_equal));
        System.out.println(user.equals(user_equal));
        System.out.println(user.getName());
        System.out.println(user.getAge());
    }
}

輸出:

true
true
Kaven
20

關于基于Consumer接口、Predicate接口初使用是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

文昌市| 定南县| 岑溪市| 平湖市| 罗源县| 津市市| 万盛区| 商丘市| 邹平县| 翁牛特旗| 高尔夫| 西昌市| 高密市| 岳阳县| 于田县| 芦溪县| 丹凤县| 阿尔山市| 太白县| 苏尼特右旗| 墨脱县| 磐石市| 永定县| 鲁甸县| 石嘴山市| 新竹县| 大石桥市| 兴城市| 吉木萨尔县| 抚顺县| 育儿| 延边| 洛宁县| 庐江县| 阿坝| 乐业县| 林口县| 文化| 永州市| 屏东县| 宜城市|