最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基礎(chǔ)之JDK1.8新特性lambda表達(dá)式詳解

 更新時(shí)間:2023年08月19日 11:22:44   作者:碼農(nóng)飛哥  
函數(shù)式接口有且僅有一個(gè)抽象方法,但是可以有多個(gè)非抽象方法的接口,函數(shù)式接口可以被隱式轉(zhuǎn)換為lambda表達(dá)式,這篇文章主要介紹了Java基礎(chǔ)之lambda表達(dá)式(JDK1.8新特性),需要的朋友可以參考下

Lambda表達(dá)式

Lambda表達(dá)式允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞進(jìn)方法中)。函數(shù)式接口有且僅有一個(gè)抽象方法,但是可以有多個(gè)非抽象方法的接口。函數(shù)式接口可以被隱式轉(zhuǎn)換為lambda表達(dá)式。

各種函數(shù)式接口

java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter

JDK1.8 新增加的函數(shù)接口:

java.util.function

java.util.function 包下包含了很多類,用來支持Java的函數(shù)式編程

接口&描述
BiConsumer<T,U>代表了一個(gè)接受兩個(gè)輸入?yún)?shù)的操作,并且不返回任何結(jié)果
BiFunction<T,U,R>代表了一個(gè)接受兩個(gè)輸入?yún)?shù)的方法,并且返回一個(gè)結(jié)果
BinaryOperaror代表了一個(gè)作用于兩個(gè)同類型操作符的操作,并且返回了操作符同類型的結(jié)果
BiPredicate<T,U>代表了一個(gè)兩個(gè)參數(shù)的boolean值方法
BooleanSupplier代表了boolean值結(jié)果的提供方
Consumer代表了接受一個(gè)輸入?yún)?shù)并且無返回的操作
DoubleBinaryOperator代表了作用于兩個(gè)double值操作符的操作,并且返回了一個(gè)double值的結(jié)果
DoubleConsumer代表了一個(gè)接受double值參數(shù)的操作,并且不返回結(jié)果
DoubleFunction代表接受一個(gè)double值參數(shù)的方法,并且有返回值
Comparator這個(gè)接口最主要的作用就是比較,其核心的方法是 compare(T o1, T o2),當(dāng) o1比o2小返回-1,當(dāng)o1等于o2返回0,當(dāng)o1大于o2返回1

Lambda的語法

(parameters) -> expression
或
(parameters) ->{ statements; }
  • 可選類型聲明:不需要聲明參數(shù)類型,編譯器可以統(tǒng)一識別參數(shù)值
  • 可選的參數(shù)圓括號:一個(gè)參數(shù)無需定義圓括號,但多個(gè)參數(shù)需要定義圓括號
  • 可選的大括號:如果主體包括了一個(gè)語句,就不需要使用大括號
  • 可選的返回關(guān)鍵字:如果主體只有一個(gè)表達(dá)式返回值,則編譯器會自動返回值,大括號需要指明表達(dá)式返回的一個(gè)數(shù)值。

Lambda 表達(dá)實(shí)例

        //1. 不需要參數(shù),返回值為5
        ()->5;
        //2. 接收一個(gè)參數(shù)(數(shù)字類型),返回其2倍的值
        x ->2*x
        //3.接受2個(gè)參數(shù)(數(shù)字),并返回他們的差值
        (x,y)->x - y;
        //4.接收2個(gè)int型整數(shù),返回他們的和
        (int x,int y)->x+y;
        //5. 接收一個(gè)String對象,并在控制臺打印,不返回任何值
        (String s)->System.out.print(s);

舉例說明

public class Java8Tester {
    public static void main(String[] args) {
   Java8Tester tester = new Java8Tester();
        //類型聲明
        MathOperation addition = (int a, int b) -> a + b;
        //不用聲明類型
        MathOperation subtraction = (a, b) -> a - b;
        //大括號中的返回語句
        MathOperation multipliaction = (int a, int b) -> {
            return a * b;
        };
        //沒有大括號及返回語句
        MathOperation division = (int a, int b) -> a / b;
        System.out.println("10+5=" + tester.operate(10, 5, addition));
        System.out.println("10-5=" + tester.operate(10, 5, subtraction));
        System.out.println("10*5=" + tester.operate(10, 5, multipliaction));
        System.out.println("10/5=" + tester.operate(10, 5, division));
        //不用括號
        GreetingService greetingService1 = message -> System.out.println("Hello " + message);
        //用括號
        GreetingService greetingService2 = (message) -> System.out.println("Hello " + message);
        greetingService1.sayMessage("Runoob");
        greetingService2.sayMessage("Google");
	 }
    interface MathOperation{
        int operation(int a, int b);
    }
    interface GreetingService{
        void sayMessage(String message);
    }
    private int operate(int a, int b, MathOperation mathOperation) {
        return mathOperation.operation(a, b);
    }
}

變量作用域

lambda 表達(dá)式只能引用標(biāo)記了final的外層局部變量,也就是說不能再lambda內(nèi)部修改定義在域外的局部變量,否則會編譯報(bào)錯。 在lambda表達(dá)式中,只能引用值不會改變的變量。 這是因?yàn)槿绻趌ambda表達(dá)式中改變變量,并發(fā)執(zhí)行多個(gè)動作時(shí)就會不安全。對于目前為止我們看到的動作不會發(fā)生這種情況。

public class Java8Test2 {
    final static String salutation = "Hello!";
    public static void main(String[] args) {
        GreetingService greetingService = message -> System.out.println(salutation + message);
        greetingService.sayMessage("Runoob");
    }
    interface GreetingService {
        void sayMessage(String message);
    }
}

處理lambda 表達(dá)式

使用lambda表達(dá)式的重點(diǎn)是延遲執(zhí)行。畢竟,如果想要立即執(zhí)行代碼,完全可以直接執(zhí)行,而無需把它包裝在一個(gè)lambda表達(dá)式中。之所以希望以后執(zhí)行代碼,這有很多原因,如:

  • 在一個(gè)單獨(dú)的線程中運(yùn)行代碼:
  • 多次運(yùn)行代碼;
  • 在算法的適當(dāng)位置運(yùn)行代碼(例如:排序中的比較操作);
  • 發(fā)生某種情況時(shí)執(zhí)行代碼(如,點(diǎn)擊了一個(gè)按鈕,數(shù)據(jù)到達(dá),等等);
  • 只在必要時(shí)才運(yùn)行代碼。

例如:假設(shè)你想要執(zhí)行一個(gè)動作n次,將這個(gè)動作和重復(fù)次數(shù)傳遞到一個(gè) repeat 方法: repeat(10,()->System.out.println("Hello,world")) 要接受這個(gè)lambda表達(dá)式,需要選擇一個(gè)函數(shù)式接口。例如,我們可以使用 Runnable 接口:

 public static void repeat(int n,Runnable action){
      for(int i=0;i<n;i++){
        action.run();
      }
 }

如果要告訴動作出現(xiàn)在某次迭代中。

/**
     * 在某次迭代中執(zhí)行動作
     * @param n
     * @param action
     */
    public static void repeat(int n, IntConsumer action) {
        for (int i = 0; i < n; i++) {
            action.accept(i);
        }
    }

變量作用域

lambda 表達(dá)式有3個(gè)部分

  • 一個(gè)代碼塊;
  • 參數(shù);
  • 自由變量的值,這里指非參數(shù)而且不在代碼中定義的變量。

函數(shù)式接口

函數(shù)接口,是指內(nèi)部只有一個(gè)抽象方法的接口。但是可以有多個(gè)非抽象方法的接口,函數(shù)式接口可以被隱式轉(zhuǎn)換為lambda表達(dá)式。

使用實(shí)例1

public class PredicateTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        /**
         *
         * Predicate<Integer> dispatcher = n -> true;
         n 是一個(gè)參數(shù)傳遞到Predicate接口的test方法
         n 如果存在test方法返回true
         */
        System.out.println("輸出所有數(shù)據(jù):");
        //傳遞參數(shù)n
        eval(list, n -> true);
//        Predicate<Integer> dispatcher = n -> true;
//        n 是一個(gè)參數(shù)傳遞到Predicate接口的test方法
//        如果n%2為0,test方法返回true
        System.out.println("******輸出所有的偶數(shù):");
        eval(list, n -> n % 2 == 0);
//        Predicate<Integer> predicate2=n->n>3
//        n是一個(gè)參數(shù)傳遞到Predicate接口的test方法
//        如果n大于3 test方法返回true
        System.out.println("輸出大于3的所有數(shù)字:");
        eval(list, n -> n > 3);
    }
    public static void eval(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {
            if (predicate.test(n)) {
                System.out.println(n+" ");
            }
        }
    }
}

使用實(shí)例2

public class CompareTest {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "pear");
        compareLength("apple", "banana", (n1, n2) -> -1);
        compareLength("banana", "pear", (n1, n2) -> 1);
        compareLength("banana", "banana", (n1, n2) -> 0);
        words.sort(Comparator.comparingInt(String::length));
    }
    public static void compareLength(String n1, String n2, Comparator comparator) {
        if (comparator.compare(n1, n2) == 0) {
            System.out.println("n1==n2" + n1 + "  " + n2);
        }
        if (comparator.compare(n1, n2) > 0) {
            System.out.println("n1>n2" + n1 + "  " + n2);
        }
        if (comparator.compare(n1, n2) < 0) {
            System.out.println("n1<n2" + n1 + "  " + n2);
        }
    }
}

使用示例3(集合排序)

現(xiàn)在我們有一個(gè)集合list,集合的里的數(shù)據(jù)類型是HashMap。那么我們?nèi)绾胃鶕?jù)HashMap中的某個(gè)key給list排序呢?

public class ListSortTest {
    public static void main(String[] args) {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("id", 2);
        map1.put("name", "張二");
        list.add(map1);
        Map<String, Object> map2 = new HashMap<>();
        map2.put("id", 1);
        map2.put("name", "張一");
        list.add(map2);
        Map<String, Object> map3 = new HashMap<>();
        map3.put("id", 3);
        map3.put("name", "張三");
        list.add(map3);
        //升序排列
        Collections.sort(list, (o1, o2) -> {
            int o1Id = (int) o1.get("id");
            int o2Id = (int) o2.get("id");
            if (o1Id > o2Id) {
                return 1;
            } else {
                return -1;
            }
        });
        //降序排列
        Collections.sort(list, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                int o1Id = (int) o1.get("id");
                int o2Id = (int) o2.get("id");
                if (o1Id > o2Id) {
                    return -1;
                } else {
                    return 1;
                }
            }
        });
    }
}

使用示例4(按照對象屬性給list排序)

public class ListSortTest2 {
    public static void main(String[] args) {
        Student student1 = new Student(1, "張三");
        Student student2 = new Student(2, "李四");
        List<Student> studentList = new ArrayList<>();
        studentList.add(student1);
        studentList.add(student2);
        //升序
        studentList.sort((o1, o2) -> {
            int o1Id = o1.getId();
            int o2Id = o2.getId();
            if (o1Id > o2Id) {
                return 1;
            } else {
                return -1;
            }
        });
        //降序
        studentList.sort((o1, o2) -> {
            int o1Id = o1.getId();
            int o2Id = o2.getId();
            if (o1Id > o2Id) {
                return -1;
            } else {
                return 1;
            }
        });
    }

使用示例4

自定義一個(gè)函數(shù)式接口

public class SimpleLambda {
    public static void main(String[] args) {
        start(()-> System.out.println("調(diào)用函數(shù)式接口"));
    }
    public static void start(MyRunnable runnable) {
        new Thread(runnable).start();
    }
    //1. 只能有一個(gè)抽象方法
    //2.默認(rèn)方法除外
    //3.可以加FunctionalInterface注解,也可以不加
    public interface MyRunnable extends Runnable {
        default void myRun() {
        }
    }
}

自定義一個(gè)函數(shù)式接口,傳入?yún)?shù),多種不同的代碼編寫特性:

public class SimpleLambda2 {
    public static void main(String[] args) {
        // 1.單行表達(dá)式,可以省略return
        run(name -> String.format(name));
        // 2.代碼塊
        run(name -> {
            String name1 = name;
            return "序列化" + name1;
        });
        //3.方法引用,靜態(tài)方法引用
        run(SimpleLambda2::toFormat);
        //4.普通方法引用
        run(new SimpleLambda2()::toFormat2);
    }
    static void run(Format format) {
        format.format("飛哥");
    }
    static String toFormat(String param) {
        return "序列化" + param;
    }
    String toFormat2(String param) {
        return "序列化" + param;
    }
    public interface Format {
        String format(String name);
    }
}

自定義一個(gè)函數(shù)式接口,帶泛型的方法型函數(shù)

public class SimpleLambda4 {
    public static void main(String[] args) {
        Apple apple = new Apple(1, "紅色", 12, "安徽");
        Banner banner1 = doBuild(apple, apple1 -> {
            Banner banner = new Banner();
            banner.setPrice(apple1.getPrice());
            banner.setColor(apple1.getColor());
            return banner;
        });
        System.out.println(banner1);
    }
    public static Banner doBuild(Apple apple, Format format) {
        return format.build(apple);
    }
    @FunctionalInterface
    public interface Format<T extends Apple, R extends Banner> {
        R build(T t);
    }
}

總結(jié)

本文詳細(xì)介紹了lambda表達(dá)式,lambda表達(dá)式是JDK1.8最重要的特性?;旧纤械膬?nèi)部類都可以用lambda表達(dá)式來表示。靈活的運(yùn)用lambda表達(dá)式和函數(shù)式接口可以大大的簡化的程序開發(fā)。

參考

Java 8 Lambda 表達(dá)式

[Java 8 函數(shù)式接口](

到此這篇關(guān)于Java基礎(chǔ)之lambda表達(dá)式(JDK1.8新特性)的文章就介紹到這了,更多相關(guān)JDK1.8新特性 lambda表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis在DAO層定義接口返回類型泛型無效的解決

    MyBatis在DAO層定義接口返回類型泛型無效的解決

    這篇文章主要介紹了MyBatis在DAO層定義接口返回類型泛型無效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 使用@RequestBody傳對象參數(shù)時(shí)碰到的坑

    使用@RequestBody傳對象參數(shù)時(shí)碰到的坑

    這篇文章主要介紹了使用@RequestBody傳對象參數(shù)時(shí)碰到的坑,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java如何讀取某個(gè)文件夾中的全部文件(包括子文件夾)

    java如何讀取某個(gè)文件夾中的全部文件(包括子文件夾)

    這篇文章主要介紹了java如何讀取某個(gè)文件夾中的全部文件(包括子文件夾),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Postman實(shí)現(xiàn)傳List<String>集合

    Postman實(shí)現(xiàn)傳List<String>集合

    這篇文章主要介紹了Postman實(shí)現(xiàn)傳List<String>集合方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java中json-diff簡單使用及對象是否一致詳解

    java中json-diff簡單使用及對象是否一致詳解

    這篇文章主要為大家介紹了java中json-diff簡單使用及對象是否一致對比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java并發(fā)鎖機(jī)制知識總結(jié)(最新整理)

    Java并發(fā)鎖機(jī)制知識總結(jié)(最新整理)

    Java?的鎖機(jī)制是并發(fā)編程的核心,用于解決多線程共享資源競爭問題,保證數(shù)據(jù)一致性和線程安全,這篇文章給大家介紹Java并發(fā)鎖機(jī)制知識總結(jié),感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • 詳解如何有效地處理Java中的多線程

    詳解如何有效地處理Java中的多線程

    在現(xiàn)代軟件開發(fā)中,多線程編程已成為提高程序性能和響應(yīng)速度的重要手段,Java提供了豐富的多線程支持,使得在Java中實(shí)現(xiàn)并發(fā)操作變得相對簡單,本文將深入探討Java多線程編程的基本概念、常見問題和最佳實(shí)踐,需要的朋友可以參考下
    2024-06-06
  • spring啟動加載程序的幾種方法介紹

    spring啟動加載程序的幾種方法介紹

    本篇文章主要介紹了spring啟動加載程序的幾種方法介紹,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • Java方法參數(shù)裝配順序詳解

    Java方法參數(shù)裝配順序詳解

    這篇文章主要介紹了Java方法參數(shù)裝配順序詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Spring?@Transactional?注解從入門到避坑指南

    Spring?@Transactional?注解從入門到避坑指南

    文章主要講解了Spring的@Transactional注解的使用場景、核心屬性詳解、事務(wù)傳播行為、隔離級別、回滾配置、底層原理以及失效場景和避免之道,并還給出了最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2026-05-05

最新評論

玉环县| 长葛市| 广宗县| 平乡县| 洛扎县| 朝阳区| 分宜县| 景谷| 竹山县| 泰兴市| 印江| 浦东新区| 潮安县| 灵璧县| 哈尔滨市| 新乡市| 凤庆县| 河南省| 都江堰市| 沁阳市| 绍兴市| 克什克腾旗| 宣汉县| 当阳市| 北碚区| 蛟河市| 尚义县| 新密市| 南郑县| 湘乡市| 磴口县| 田阳县| 民县| 繁峙县| 怀集县| 玉环县| 城口县| 射阳县| 洛阳市| 和田市| 玉山县|