6 Lambda表達式

1.Lambda表達式

1.1體驗Lambda表達式【理解】

  • 案例需求

    啟動一個線程,在控制臺輸出一句話:多線程程序啟動了

  • 實現(xiàn)方式一

    • 實現(xiàn)步驟
      • 定義一個類MyRunnable實現(xiàn)Runnable接口,重寫run()方法
      • 創(chuàng)建MyRunnable類的對象
      • 創(chuàng)建Thread類的對象,把MyRunnable的對象作為構(gòu)造參數(shù)傳遞
      • 啟動線程
  • 實現(xiàn)方式二

    • 匿名內(nèi)部類的方式改進
  • 實現(xiàn)方式三

    • Lambda表達式的方式改進
  • 代碼演示

    //方式一的線程類
    public class MyRunnable implements Runnable {
    
        @Override
        public void run() {
            System.out.println("多線程程序啟動了");
        }
    }
    
    public class LambdaDemo {
        public static void main(String[] args) {
            //方式一
    //        MyRunnable my = new MyRunnable();
    //        Thread t = new Thread(my);
    //        t.start();
    
            //方式二
    //        new Thread(new Runnable() {
    //            @Override
    //            public void run() {
    //                System.out.println("多線程程序啟動了");
    //            }
    //        }).start();
    
            //方式三
            new Thread( () -> {
                System.out.println("多線程程序啟動了");
            } ).start();
        }
    }
    
  • 函數(shù)式編程思想概述

    函數(shù)式思想則盡量忽略面向?qū)ο蟮膹碗s語法:“強調(diào)做什么,而不是以什么形式去做”

    而我們要學習的Lambda表達式就是函數(shù)式思想的體現(xiàn)

1.2Lambda表達式的標準格式【理解】

  • 格式:

    ? (形式參數(shù)) -> {代碼塊}

    • 形式參數(shù):如果有多個參數(shù),參數(shù)之間用逗號隔開;如果沒有參數(shù),留空即可

    • ->:由英文中畫線和大于符號組成,固定寫法。代表指向動作

    • 代碼塊:是我們具體要做的事情,也就是以前我們寫的方法體內(nèi)容

  • 組成Lambda表達式的三要素:

    • 形式參數(shù),箭頭,代碼塊

1.3Lambda表達式練習1【應用】

  • Lambda表達式的使用前提

    • 有一個接口

    • 接口中有且僅有一個抽象方法

  • 練習描述

    ? 無參無返回值抽象方法的練習

  • 操作步驟

    • 定義一個接口(Eatable),里面定義一個抽象方法:void eat();

    • 定義一個測試類(EatableDemo),在測試類中提供兩個方法

      • 一個方法是:useEatable(Eatable e)

      • 一個方法是主方法,在主方法中調(diào)用useEatable方法

  • 示例代碼

    //接口
    public interface Eatable {
        void eat();
    }
    //實現(xiàn)類
    public class EatableImpl implements Eatable {
        @Override
        public void eat() {
            System.out.println("一天一蘋果,醫(yī)生遠離我");
        }
    }
    //測試類
    public class EatableDemo {
        public static void main(String[] args) {
            //在主方法中調(diào)用useEatable方法
            Eatable e = new EatableImpl();
            useEatable(e);
    
            //匿名內(nèi)部類
            useEatable(new Eatable() {
                @Override
                public void eat() {
                    System.out.println("一天一蘋果,醫(yī)生遠離我");
                }
            });
    
            //Lambda表達式
            useEatable(() -> {
                System.out.println("一天一蘋果,醫(yī)生遠離我");
            });
        }
    
        private static void useEatable(Eatable e) {
            e.eat();
        }
    }
    

1.4Lambda表達式練習2【應用】

  • 練習描述

    有參無返回值抽象方法的練習

  • 操作步驟

    • 定義一個接口(Flyable),里面定義一個抽象方法:void fly(String s);

    • 定義一個測試類(FlyableDemo),在測試類中提供兩個方法

      • 一個方法是:useFlyable(Flyable f)

      • 一個方法是主方法,在主方法中調(diào)用useFlyable方法

  • 示例代碼

    public interface Flyable {
        void fly(String s);
    }
    
    public class FlyableDemo {
        public static void main(String[] args) {
            //在主方法中調(diào)用useFlyable方法
            //匿名內(nèi)部類
            useFlyable(new Flyable() {
                @Override
                public void fly(String s) {
                    System.out.println(s);
                    System.out.println("飛機自駕游");
                }
            });
            System.out.println("--------");
    
            //Lambda
            useFlyable((String s) -> {
                System.out.println(s);
                System.out.println("飛機自駕游");
            });
    
        }
    
        private static void useFlyable(Flyable f) {
            f.fly("風和日麗,晴空萬里");
        }
    }
    

1.5Lambda表達式練習3【應用】

  • 練習描述

    有參有返回值抽象方法的練習

  • 操作步驟

    • 定義一個接口(Addable),里面定義一個抽象方法:int add(int x,int y);

    • 定義一個測試類(AddableDemo),在測試類中提供兩個方法

      • 一個方法是:useAddable(Addable a)

      • 一個方法是主方法,在主方法中調(diào)用useAddable方法

  • 示例代碼

    public interface Addable {
        int add(int x,int y);
    }
    
    public class AddableDemo {
        public static void main(String[] args) {
            //在主方法中調(diào)用useAddable方法
            useAddable((int x,int y) -> {
                return x + y;
            });
    
        }
    
        private static void useAddable(Addable a) {
            int sum = a.add(10, 20);
            System.out.println(sum);
        }
    }
    

1.6Lambda表達式的省略模式【應用】

  • 省略的規(guī)則

    • 參數(shù)類型可以省略。但是有多個參數(shù)的情況下,不能只省略一個
    • 如果參數(shù)有且僅有一個,那么小括號可以省略
    • 如果代碼塊的語句只有一條,可以省略大括號和分號,和return關(guān)鍵字
  • 代碼演示

    public interface Addable {
        int add(int x, int y);
    }
    
    public interface Flyable {
        void fly(String s);
    }
    
    public class LambdaDemo {
        public static void main(String[] args) {
    //        useAddable((int x,int y) -> {
    //            return x + y;
    //        });
            //參數(shù)的類型可以省略
            useAddable((x, y) -> {
                return x + y;
            });
    
    //        useFlyable((String s) -> {
    //            System.out.println(s);
    //        });
            //如果參數(shù)有且僅有一個,那么小括號可以省略
    //        useFlyable(s -> {
    //            System.out.println(s);
    //        });
    
            //如果代碼塊的語句只有一條,可以省略大括號和分號
            useFlyable(s -> System.out.println(s));
    
            //如果代碼塊的語句只有一條,可以省略大括號和分號,如果有return,return也要省略掉
            useAddable((x, y) -> x + y);
        }
    
        private static void useFlyable(Flyable f) {
            f.fly("風和日麗,晴空萬里");
        }
    
        private static void useAddable(Addable a) {
            int sum = a.add(10, 20);
            System.out.println(sum);
        }
    }
    

1.7Lambda表達式的注意事項【理解】

  • 使用Lambda必須要有接口,并且要求接口中有且僅有一個抽象方法

  • 必須有上下文環(huán)境,才能推導出Lambda對應的接口

    • 根據(jù)局部變量的賦值得知Lambda對應的接口

      ? Runnable r = () -> System.out.println("Lambda表達式");

    • 根據(jù)調(diào)用方法的參數(shù)得知Lambda對應的接口

      ? new Thread(() -> System.out.println("Lambda表達式")).start();

1.8Lambda表達式和匿名內(nèi)部類的區(qū)別【理解】

  • 所需類型不同

    • 匿名內(nèi)部類:可以是接口,也可以是抽象類,還可以是具體類
    • Lambda表達式:只能是接口
  • 使用限制不同

    • 如果接口中有且僅有一個抽象方法,可以使用Lambda表達式,也可以使用匿名內(nèi)部類

    • 如果接口中多于一個抽象方法,只能使用匿名內(nèi)部類,而不能使用Lambda表達式

  • 實現(xiàn)原理不同

    • 匿名內(nèi)部類:編譯之后,產(chǎn)生一個單獨的.class字節(jié)碼文件
    • Lambda表達式:編譯之后,沒有一個單獨的.class字節(jié)碼文件。對應的字節(jié)碼會在運行的時候動態(tài)生成

2.接口組成更新

2.1接口組成更新概述【理解】

  • 常量

    public static final

  • 抽象方法

    public abstract

  • 默認方法(Java 8)

  • 靜態(tài)方法(Java 8)

  • 私有方法(Java 9)

2.2接口中默認方法【應用】

  • 格式

    public default 返回值類型 方法名(參數(shù)列表) { }

  • 范例

    public default void show3() { 
    }
    
  • 注意事項

    • 默認方法不是抽象方法,所以不強制被重寫。但是可以被重寫,重寫的時候去掉default關(guān)鍵字

    • public可以省略,default不能省略

2.3接口中靜態(tài)方法【應用】

  • 格式

    public static 返回值類型 方法名(參數(shù)列表) { }

  • 范例

    public static void show() {
    }
    
  • 注意事項

    • 靜態(tài)方法只能通過接口名調(diào)用,不能通過實現(xiàn)類名或者對象名調(diào)用

    • public可以省略,static不能省略

2.4接口中私有方法【應用】

  • 私有方法產(chǎn)生原因

    Java 9中新增了帶方法體的私有方法,這其實在Java 8中就埋下了伏筆:Java 8允許在接口中定義帶方法體的默認方法和靜態(tài)方法。這樣可能就會引發(fā)一個問題:當兩個默認方法或者靜態(tài)方法中包含一段相同的代碼實現(xiàn)時,程序必然考慮將這段實現(xiàn)代碼抽取成一個共性方法,而這個共性方法是不需要讓別人使用的,因此用私有給隱藏起來,這就是Java 9增加私有方法的必然性

  • 定義格式

    • 格式1

      private 返回值類型 方法名(參數(shù)列表) { }

    • 范例1

      private void show() {  
      }
      
    • 格式2

      private static 返回值類型 方法名(參數(shù)列表) { }

    • 范例2

      private static void method() {  
      }
      
  • 注意事項

    • 默認方法可以調(diào)用私有的靜態(tài)方法和非靜態(tài)方法
    • 靜態(tài)方法只能調(diào)用私有的靜態(tài)方法

3.方法引用

3.1體驗方法引用【理解】

  • 方法引用的出現(xiàn)原因

    在使用Lambda表達式的時候,我們實際上傳遞進去的代碼就是一種解決方案:拿參數(shù)做操作

    那么考慮一種情況:如果我們在Lambda中所指定的操作方案,已經(jīng)有地方存在相同方案,那是否還有必要再寫重復邏輯呢?答案肯定是沒有必要

    那我們又是如何使用已經(jīng)存在的方案的呢?

    這就是我們要講解的方法引用,我們是通過方法引用來使用已經(jīng)存在的方案

  • 代碼演示

    public interface Printable {
        void printString(String s);
    }
    
    public class PrintableDemo {
        public static void main(String[] args) {
            //在主方法中調(diào)用usePrintable方法
    //        usePrintable((String s) -> {
    //            System.out.println(s);
    //        });
          //Lambda簡化寫法
            usePrintable(s -> System.out.println(s));
    
            //方法引用
            usePrintable(System.out::println);
    
        }
    
        private static void usePrintable(Printable p) {
            p.printString("愛生活愛Java");
        }
    }
    
    

3.2方法引用符【理解】

  • 方法引用符

    :: 該符號為引用運算符,而它所在的表達式被稱為方法引用

  • 推導與省略

    • 如果使用Lambda,那么根據(jù)“可推導就是可省略”的原則,無需指定參數(shù)類型,也無需指定的重載形式,它們都將被自動推導
    • 如果使用方法引用,也是同樣可以根據(jù)上下文進行推導
    • 方法引用是Lambda的孿生兄弟

3.3引用類方法【應用】

? 引用類方法,其實就是引用類的靜態(tài)方法

  • 格式

    類名::靜態(tài)方法

  • 范例

    Integer::parseInt

    Integer類的方法:public static int parseInt(String s) 將此String轉(zhuǎn)換為int類型數(shù)據(jù)

  • 練習描述

    • 定義一個接口(Converter),里面定義一個抽象方法 int convert(String s);

    • 定義一個測試類(ConverterDemo),在測試類中提供兩個方法

      • 一個方法是:useConverter(Converter c)

      • 一個方法是主方法,在主方法中調(diào)用useConverter方法

  • 代碼演示

    public interface Converter {
        int convert(String s);
    }
    
    public class ConverterDemo {
        public static void main(String[] args) {
    
          //Lambda寫法
            useConverter(s -> Integer.parseInt(s));
    
            //引用類方法
            useConverter(Integer::parseInt);
    
        }
    
        private static void useConverter(Converter c) {
            int number = c.convert("666");
            System.out.println(number);
        }
    }
    
  • 使用說明

    Lambda表達式被類方法替代的時候,它的形式參數(shù)全部傳遞給靜態(tài)方法作為參數(shù)

3.4引用對象的實例方法【應用】

? 引用對象的實例方法,其實就引用類中的成員方法

  • 格式

    對象::成員方法

  • 范例

    "HelloWorld"::toUpperCase

    String類中的方法:public String toUpperCase() 將此String所有字符轉(zhuǎn)換為大寫

  • 練習描述

    • 定義一個類(PrintString),里面定義一個方法

      public void printUpper(String s):把字符串參數(shù)變成大寫的數(shù)據(jù),然后在控制臺輸出

    • 定義一個接口(Printer),里面定義一個抽象方法

      void printUpperCase(String s)

    • 定義一個測試類(PrinterDemo),在測試類中提供兩個方法

      • 一個方法是:usePrinter(Printer p)
      • 一個方法是主方法,在主方法中調(diào)用usePrinter方法
  • 代碼演示

    public class PrintString {
        //把字符串參數(shù)變成大寫的數(shù)據(jù),然后在控制臺輸出
        public void printUpper(String s) {
            String result = s.toUpperCase();
            System.out.println(result);
        }
    }
    
    public interface Printer {
        void printUpperCase(String s);
    }
    
    public class PrinterDemo {
        public static void main(String[] args) {
    
          //Lambda簡化寫法
            usePrinter(s -> System.out.println(s.toUpperCase()));
    
            //引用對象的實例方法
            PrintString ps = new PrintString();        //引用對象在Lambda外面,所以用引用對象的實例方法!!!!!!!!!!!!!
            usePrinter(ps::printUpper);
    
        }
    
        private static void usePrinter(Printer p) {
            p.printUpperCase("HelloWorld");
        }
    }
    
    
  • 使用說明

    Lambda表達式被對象的實例方法替代的時候,它的形式參數(shù)全部傳遞給該方法作為參數(shù)

3.5引用類的實例方法【應用】

? 引用類的實例方法,其實就是引用類中的成員方法

  • 格式

    類名::成員方法

  • 范例

    String::substring

    public String substring(int beginIndex,int endIndex)

    從beginIndex開始到endIndex結(jié)束,截取字符串。返回一個子串,子串的長度為endIndex-beginIndex

  • 練習描述

    • 定義一個接口(MyString),里面定義一個抽象方法:

      String mySubString(String s,int x,int y);

    • 定義一個測試類(MyStringDemo),在測試類中提供兩個方法

      • 一個方法是:useMyString(MyString my)

      • 一個方法是主方法,在主方法中調(diào)用useMyString方法

  • 代碼演示

    public interface MyString {
        String mySubString(String s,int x,int y);
    }
    
    public class MyStringDemo {
        public static void main(String[] args) {
          //Lambda簡化寫法
            useMyString((s,x,y) -> s.substring(x,y));
    
            //引用類的實例方法
            useMyString(String::substring);                    引用對象s作為參數(shù)傳進Lambda里面,所以用引用類的實例方法!!!!!!!
    
        }
    
        private static void useMyString(MyString my) {
            String s = my.mySubString("HelloWorld", 2, 5);
            System.out.println(s);
        }
    }
    
  • 使用說明

    ? Lambda表達式被類的實例方法替代的時候
    ? 第一個參數(shù)作為調(diào)用者
    ? 后面的參數(shù)全部傳遞給該方法作為參數(shù)

3.6引用構(gòu)造器【應用】

? 引用構(gòu)造器,其實就是引用構(gòu)造方法

  • l格式

    類名::new

  • 范例

    Student::new

  • 練習描述

    • 定義一個類(Student),里面有兩個成員變量(name,age)

      并提供無參構(gòu)造方法和帶參構(gòu)造方法,以及成員變量對應的get和set方法

    • 定義一個接口(StudentBuilder),里面定義一個抽象方法

      Student build(String name,int age);

    • 定義一個測試類(StudentDemo),在測試類中提供兩個方法

      • 一個方法是:useStudentBuilder(StudentBuilder s)

      • 一個方法是主方法,在主方法中調(diào)用useStudentBuilder方法

  • 代碼演示

    public class Student {
        private String name;
        private int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    public interface StudentBuilder {
        Student build(String name,int age);
    }
    
    public class StudentDemo {
        public static void main(String[] args) {
    
          //Lambda簡化寫法
            useStudentBuilder((name,age) -> new Student(name,age));
    
            //引用構(gòu)造器
            useStudentBuilder(Student::new);
    
        }
    
        private static void useStudentBuilder(StudentBuilder sb) {
            Student s = sb.build("林青霞", 30);
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
    
  • 使用說明

    Lambda表達式被構(gòu)造器替代的時候,它的形式參數(shù)全部傳遞給構(gòu)造器作為參數(shù)

1.3函數(shù)式接口作為方法的返回值【應用】

  • 需求描述

    定義一個類(ComparatorDemo),在類中提供兩個方法

    一個方法是:Comparator<String> getComparator() 方法返回值Comparator是一個函數(shù)式接口

    一個方法是主方法,在主方法中調(diào)用getComparator方法

  • 代碼演示

    public class ComparatorDemo {
        public static void main(String[] args) {
            //定義集合,存儲字符串元素
            ArrayList<String> array = new ArrayList<String>();
    
            array.add("cccc");
            array.add("aa");
            array.add("b");
            array.add("ddd");
    
            System.out.println("排序前:" + array);
    
            Collections.sort(array, getComparator());
    
            System.out.println("排序后:" + array);
    
        }
    
        private static Comparator<String> getComparator() {
            //匿名內(nèi)部類的方式實現(xiàn)
    //        return new Comparator<String>() {
    //            @Override
    //            public int compare(String s1, String s2) {
    //                return s1.length()-s2.length();
    //            }
    //        };
            
          //Lambda方式實現(xiàn)
            return (s1, s2) -> s1.length() - s2.length();
        }
    }
    

1.4常用函數(shù)式接口之Supplier【應用】 無參數(shù)進入,有參數(shù)輸出

  • Supplier接口

    Supplier<T>接口也被稱為生產(chǎn)型接口,如果我們指定了接口的泛型是什么類型,那么接口中的get方法就會生產(chǎn)什么類型的數(shù)據(jù)供我們使用。

  • 常用方法

    只有一個無參的方法

    方法名 說明
    T get() 按照某種實現(xiàn)邏輯(由Lambda表達式實現(xiàn))返回一個數(shù)據(jù)
  • 代碼演示

    public class SupplierDemo {
        public static void main(String[] args) {
    
            String s = getString(() -> "林青霞");
            System.out.println(s);
            
            Integer i = getInteger(() -> 30);
            System.out.println(i);
        }
    
        //定義一個方法,返回一個整數(shù)數(shù)據(jù)
        private static Integer getInteger(Supplier<Integer> sup) {
            return sup.get();
        }
    
        //定義一個方法,返回一個字符串數(shù)據(jù)
        private static String getString(Supplier<String> sup) {
            return sup.get();
        }
    
    }
    

1.5Supplier接口練習之獲取最大值【應用】

  • 案例需求

    定義一個類(SupplierTest),在類中提供兩個方法

    一個方法是:int getMax(Supplier<Integer> sup) 用于返回一個int數(shù)組中的最大值

    一個方法是主方法,在主方法中調(diào)用getMax方法

  • 示例代碼

    public class SupplierTest {
        public static void main(String[] args) {
            //定義一個int數(shù)組
            int[] arr = {19, 50, 28, 37, 46};
    
            int maxValue = getMax(()-> {
               int max = arr[0];
    
               for(int i=1; i<arr.length; i++) {
                   if(arr[i] > max) {
                       max = arr[i];
                   }
               }
    
               return max;
            });
    
            System.out.println(maxValue);
    
        }
    
        //返回一個int數(shù)組中的最大值
        private static int getMax(Supplier<Integer> sup) {
            return sup.get();
        }
    }
    

1.6常用函數(shù)式接口之Consumer【應用】

  • Consumer接口

    Consumer<T>接口也被稱為消費型接口,它消費的數(shù)據(jù)的數(shù)據(jù)類型由泛型指定

  • 常用方法

    Consumer<T>:包含兩個方法

    方法名 說明
    void accept(T t) 對給定的參數(shù)執(zhí)行此操作
    default Consumer<T> andThen(Consumer after) 返回一個組合的Consumer,依次執(zhí)行此操作,然后執(zhí)行 after操作
  • 代碼演示

    public class ConsumerDemo {
        public static void main(String[] args) {
          //操作一
            operatorString("林青霞", s -> System.out.println(s));
          //操作二
            operatorString("林青霞", s -> System.out.println(new StringBuilder(s).reverse().toString()));
            
            System.out.println("--------");
          //傳入兩個操作使用andThen完成
            operatorString("林青霞", s -> System.out.println(s), s -> System.out.println(new StringBuilder(s).reverse().toString()));
        }
    
        //定義一個方法,用不同的方式消費同一個字符串數(shù)據(jù)兩次
        private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {
    //        con1.accept(name);
    //        con2.accept(name);
            con1.andThen(con2).accept(name);
        }
    
        //定義一個方法,消費一個字符串數(shù)據(jù)
        private static void operatorString(String name, Consumer<String> con) {
            con.accept(name);
        }
    }
    

1.7Consumer接口練習之按要求打印信息【應用】

  • 案例需求

    String[] strArray = {"林青霞,30", "張曼玉,35", "王祖賢,33"};

    字符串數(shù)組中有多條信息,請按照格式:“姓名:XX,年齡:XX"的格式將信息打印出來

    要求:

    把打印姓名的動作作為第一個Consumer接口的Lambda實例

    把打印年齡的動作作為第二個Consumer接口的Lambda實例

    將兩個Consumer接口按照順序組合到一起使用

  • 示例代碼

    public class ConsumerTest {
        public static void main(String[] args) {
            String[] strArray = {"林青霞,30", "張曼玉,35", "王祖賢,33"};
    
            printInfo(strArray, str -> System.out.print("姓名:" + str.split(",")[0]),
                    str -> System.out.println(",年齡:" + Integer.parseInt(str.split(",")[1])));
        }
    
        private static void printInfo(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
            for (String str : strArray) {
                con1.andThen(con2).accept(str);
            }
        }
    }
    

1.8常用函數(shù)式接口之Predicate【應用】

  • Predicate接口

    Predicate<T>接口通常用于判斷參數(shù)是否滿足指定的條件

  • 常用方法

    方法名 說明
    boolean test(T t) 對給定的參數(shù)進行判斷(判斷邏輯由Lambda表達式實現(xiàn)),返回一個布爾值
    default Predicate<T> negate() 返回一個邏輯的否定,對應邏輯非
    default Predicate<T> and(Predicate other) 返回一個組合判斷,對應短路與
    default Predicate<T> or(Predicate other) 返回一個組合判斷,對應短路或
  • 代碼演示

    public class PredicateDemo01 {
        public static void main(String[] args) {
            boolean b1 = checkString("hello", s -> s.length() > 8);
            System.out.println(b1);
    
            boolean b2 = checkString("helloworld",s -> s.length() > 8);
            System.out.println(b2);
    
        }
    
        //判斷給定的字符串是否滿足要求
        private static boolean checkString(String s, Predicate<String> pre) {
    //        return !pre.test(s);
            return pre.negate().test(s);
        }
    }
    
    public class PredicateDemo02 {
        public static void main(String[] args) {
            boolean b1 = checkString("hello", s -> s.length() > 8);
            System.out.println(b1);
            boolean b2 = checkString("helloworld", s -> s.length() > 8);
            System.out.println(b2);
    
            boolean b3 = checkString("hello",s -> s.length() > 8, s -> s.length() < 15);
            System.out.println(b3);
    
            boolean b4 = checkString("helloworld",s -> s.length() > 8, s -> s.length() < 15);
            System.out.println(b4);
        }
    
        //同一個字符串給出兩個不同的判斷條件,最后把這兩個判斷的結(jié)果做邏輯與運算的結(jié)果作為最終的結(jié)果
        private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
            return pre1.or(pre2).test(s);
        }
    
        //判斷給定的字符串是否滿足要求
        private static boolean checkString(String s, Predicate<String> pre) {
            return pre.test(s);
        }
    }
    

1.9Predicate接口練習之篩選滿足條件數(shù)據(jù)【應用】

  • 練習描述

    • String[] strArray = {"林青霞,30", "柳巖,34", "張曼玉,35", "貂蟬,31", "王祖賢,33"};

    • 字符串數(shù)組中有多條信息,請通過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中,并遍歷ArrayList集合

    • 同時滿足如下要求:姓名長度大于2;年齡大于33

  • 分析

    • 有兩個判斷條件,所以需要使用兩個Predicate接口,對條件進行判斷

    • 必須同時滿足兩個條件,所以可以使用and方法連接兩個判斷條件

  • 示例代碼

    public class PredicateTest {
        public static void main(String[] args) {
            String[] strArray = {"林青霞,30", "柳巖,34", "張曼玉,35", "貂蟬,31", "王祖賢,33"};
    
            ArrayList<String> array = myFilter(strArray, s -> s.split(",")[0].length() > 2,
                    s -> Integer.parseInt(s.split(",")[1]) > 33);
    
            for (String str : array) {
                System.out.println(str);
            }
        }
    
        //通過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中
        private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2) {
            //定義一個集合
            ArrayList<String> array = new ArrayList<String>();
    
            //遍歷數(shù)組
            for (String str : strArray) {
                if (pre1.and(pre2).test(str)) {
                    array.add(str);
                }
            }
    
            return array;
        }
    }
    

1.10常用函數(shù)式接口之Function【應用】

  • Function接口

    Function<T,R>接口通常用于對參數(shù)進行處理,轉(zhuǎn)換(處理邏輯由Lambda表達式實現(xiàn)),然后返回一個新的值

  • 常用方法

    方法名 說明
    R apply(T t) 將此函數(shù)應用于給定的參數(shù)
    default <V> Function andThen(Function after) 返回一個組合函數(shù),首先將該函數(shù)應用于輸入,然后將after函數(shù)應用于結(jié)果
  • 代碼演示

    public class FunctionDemo {
        public static void main(String[] args) {
          //操作一
            convert("100",s -> Integer.parseInt(s));
          //操作二
            convert(100,i -> String.valueOf(i + 566));
          
            //使用andThen的方式連續(xù)執(zhí)行兩個操作
            convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 566));
        }
    
        //定義一個方法,把一個字符串轉(zhuǎn)換int類型,在控制臺輸出
        private static void convert(String s, Function<String,Integer> fun) {
    //        Integer i = fun.apply(s);
            int i = fun.apply(s);
            System.out.println(i);
        }
    
    
        //定義一個方法,把一個int類型的數(shù)據(jù)加上一個整數(shù)之后,轉(zhuǎn)為字符串在控制臺輸出
        private static void convert(int i, Function<Integer,String> fun) {
            String s = fun.apply(i);
            System.out.println(s);
        }
    
    
        //定義一個方法,把一個字符串轉(zhuǎn)換int類型,把int類型的數(shù)據(jù)加上一個整數(shù)之后,轉(zhuǎn)為字符串在控制臺輸出
        private static void convert(String s, Function<String,Integer> fun1, Function<Integer,String> fun2) {
    
            String ss = fun1.andThen(fun2).apply(s);
            System.out.println(ss);
        }
    
    }
    

1.11Function接口練習之按照指定要求操作數(shù)據(jù)【應用】

  • 練習描述

    • String s = "林青霞,30";

    • 請按照我指定的要求進行操作:

      1:將字符串截取得到數(shù)字年齡部分

      2:將上一步的年齡字符串轉(zhuǎn)換成為int類型的數(shù)據(jù)

      3:將上一步的int數(shù)據(jù)加70,得到一個int結(jié)果,在控制臺輸出

    • 請通過Function接口來實現(xiàn)函數(shù)拼接

  • 示例代碼

    public class FunctionTest {
        public static void main(String[] args) {
            String s = "林青霞,30";
            convert(s, ss -> ss.split(",")[1], Integer::parseInt, i -> i + 70);
        }
    
        private static void convert(String s, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) {
            int i = fun1.andThen(fun2).andThen(fun3).apply(s);
            System.out.println(i);
        }
    }
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • DAY 05 1、 public classArrayDemo { public static void mai...
    周書達閱讀 833評論 0 0
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 3,205評論 0 3
  • Java經(jīng)典問題算法大全 /*【程序1】 題目:古典問題:有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子...
    趙宇_阿特奇閱讀 2,077評論 0 2
  • 多態(tài) 任何域的訪問操作都將有編譯器解析,如果某個方法是靜態(tài)的,它的行為就不具有多態(tài)性 java默認對象的銷毀順序與...
    yueyue_projects閱讀 1,093評論 0 1
  • 佩聰老師,廣西民族大學相思湖學院 設(shè)計學院視覺傳達設(shè)計專業(yè)。美術(shù)專業(yè)基礎(chǔ)扎實,擅長設(shè)計,色彩,素描。從事美術(shù)...
    10001吧閱讀 444評論 0 0

友情鏈接更多精彩內(nèi)容