zoukankan      html  css  js  c++  java
  • Lambda表达式

    函数式接口

    函数式接口在Java中是指:有且仅有一个抽象方法的接口。
    函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可
    以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。
    备注:“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实
    底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部
    类的“语法糖”,但是二者在原理上是不同的。

    @FunctionalInterface注解

    @FunctionalInterface
    public interface ParentInterface {
        String method();
    }
    

     

    性能浪费的日志案例
    注:日志可以帮助我们快速的定位问题,记录程序运行过程中的情况,以便项目的监控和优化。
    一种典型的场景就是对参数进行有条件使用,例如对日志消息进行拼接后,在满足条件的情况下进行打印输出:

      1 package com.lamda;
      2 
      3 import org.junit.Test;
      4 
      5 import java.util.*;
      6 import java.util.function.Consumer;
      7 import java.util.function.Function;
      8 import java.util.function.Predicate;
      9 import java.util.function.Supplier;
     10 
     11 public class DemoChild {
     12     /**
     13      * 自定义函数式编程
     14      */
     15     @Test
     16     public void test01() {
     17         doSomeThing(() -> {
     18             System.out.println("1111");
     19             return "";
     20         });
     21     }
     22 
     23     private static void doSomeThing(ParentInterface child) {
     24         child.method();
     25     }
     26 
     27     //延迟加载
     28     @Test
     29     public void test02() {
     30         String msgA = "a";
     31         String msgB = "ab";
     32         String msgC = "acb";
     33         log(1, () -> {
     34             return msgA + msgB + msgC;
     35         });
     36     }
     37 
     38     public void log(int level, ParentInterface p) {
     39         if (level == 1) {
     40             System.out.println(p.method());
     41         }
     42     }
     43 
     44     //作为参数
     45     @Test
     46     public void test03() {
     47         startThread(() -> {
     48             System.out.println("abc");
     49         });
     50     }
     51 
     52     public static void startThread(Runnable task) {
     53         new Thread(task).start();
     54     }
     55 
     56     //返回值
     57     private static Comparator<String> newComparator() {
     58         return (a, b) -> b.length() - a.length();
     59     }
     60 
     61     @Test
     62     public void test04() {
     63         String[] array = {"abc", "bcd", "bbcd"};
     64         Arrays.sort(array, newComparator());
     65         System.out.println(Arrays.toString(array));
     66     }
     67 
     68     //另外一种排序写法
     69     private void sortOrder() {
     70         ArrayList<String> list = new ArrayList<String>();
     71         list.add("cba");
     72         list.add("aba");
     73         list.add("sba");
     74         list.add("nba");
     75         //排序方法  按照第一个单词的降序
     76         Collections.sort(list, new Comparator<String>() {
     77             @Override
     78             public int compare(String o1, String o2) {
     79                 return o2.charAt(0) - o1.charAt(0);
     80             }
     81         });
     82     }
     83 
     84     /**
     85      * java.util.function.Supplier<T> 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对
     86      * 象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象
     87      * 数据。
     88      * 打印结果 Helloworld
     89      */
     90     @Test
     91     public void test05() {
     92         String msgA = "Hello";
     93         String msgB = "world";
     94         System.out.println(get(() -> msgA + msgB));
     95     }
     96 
     97     public static String get(Supplier<String> p) {
     98         return p.get();
     99     }
    100 
    101     //案例求最大值
    102     @Test
    103     public void test06() {
    104         int[] array = {2, 183, 1, 9};
    105         Integer max = getMax(() -> {
    106             int num = array[0];
    107             for (int i : array) {
    108                 if (i > num)
    109                     num = i;
    110             }
    111             return num;
    112 
    113         });
    114         System.out.println(max);
    115     }
    116 
    117     public static Integer getMax(Supplier<Integer> p) {
    118         return p.get();
    119     }
    120 
    121     /**
    122      * java.util.function.Consumer<T> 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,
    123      * 其数据类型由泛型决定。
    124      */
    125     @Test
    126     public void test7() {
    127         consumeStr(s -> System.out.println(s.toUpperCase()),
    128                 s -> System.out.println(s.toLowerCase())
    129         );
    130     }
    131 
    132     public void consumeStr(Consumer<String> s, Consumer<String> b) {
    133         s.andThen(b).accept("zhaNgSAN");
    134     }
    135 
    136     //demo,打印数组
    137     public static void printInfo(Consumer<String> a, Consumer<String> b, String[] arr) {
    138         for (String info : arr) {
    139             a.andThen(b).accept(info);
    140         }
    141     }
    142 
    143     @Test
    144     public void test8() {
    145         String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男"};
    146         printInfo(s -> System.out.println(s.split(",")[0]),
    147                 s -> System.out.println(s.split(",")[1]),
    148                 array
    149         );
    150     }
    151 
    152     /**
    153      * 有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用
    154      * java.util.function.Predicate<T> 接口。
    155      */
    156     @Test
    157     public void test9() {
    158         demo9(s -> s.length() > 5);
    159     }
    160 
    161     private void demo9(Predicate<String> p) {
    162         boolean helloWorld = p.test("HelloWorld");
    163         System.out.println(helloWorld);
    164     }
    165 
    166     /**
    167      * 既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
    168      * 现“并且”的效果时,可以使用default方法 and 。其JDK源码为:
    169      */
    170     @Test
    171     public void test10() {
    172         demo10(s -> s.contains("H"), d -> d.contains("D"));
    173     }
    174 
    175     private void demo10(Predicate<String> p, Predicate<String> b) {
    176         boolean helloWorld = p.and(b).test("HelloWorld");
    177         System.out.println(helloWorld);
    178     }
    179 
    180     /**
    181      * 既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
    182      * 现“并且”的效果时,可以使用default方法 and 。其JDK源码为:
    183      */
    184     @Test
    185     public void test11() {
    186         demo11(a -> a.contains("H"),
    187                 b -> b.contains("e")
    188         );
    189     }
    190 
    191     private void demo11(Predicate<String> p, Predicate<String> b) {
    192         boolean helloWorld = p.or(b).or(b).test("HelloWorld");
    193         System.out.println(helloWorld);
    194     }
    195 
    196     /**
    197      * 既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
    198      * 现“并且”的效果时,可以使用default方法 and 。其JDK源码为:
    199      */
    200     @Test
    201     public void test12() {
    202         demo12(a -> a.contains("b"),
    203                 b -> b.length() > 11
    204         );
    205     }
    206 
    207     private void demo12(Predicate<String> p, Predicate<String> b) {
    208         boolean helloWorld = p.negate().test("HelloWorld");
    209         System.out.println(helloWorld);
    210     }
    211 
    212     /**
    213      * 既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“与”逻辑连接起来实
    214      * 现“并且”的效果时,可以使用default方法 and 。其JDK源码为:
    215      */
    216     @Test
    217     public void test13() {
    218         demo13(a -> a.contains("b"),
    219                 b -> b.length() > 11
    220         );
    221     }
    222 
    223     private void demo13(Predicate<String> p, Predicate<String> b) {
    224         boolean helloWorld = p.negate().test("HelloWorld");
    225         System.out.println(helloWorld);
    226     }
    227 
    228     /**
    229      * 数组当中有多条“姓名+性别”的信息如下,请通过 Predicate 接口的拼装将符合要求的字符串筛选到集合
    230      * ArrayList 中,需要同时满足两个条件:
    231      * 1. 必须为女生;
    232      * 2. 姓名为4个字。
    233      */
    234     @Test
    235     public void test14() {
    236         String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "杨颖,女", "杨幂,女"};
    237         List list = demo14(array,
    238                 s -> "女".equals(s.split(",")[1]),
    239                 s -> s.split(",")[0].length() == 4
    240         );
    241         System.out.println(list);
    242 
    243     }
    244 
    245     private List demo14(String[] array, Predicate<String> p, Predicate<String> b) {
    246         List data = new ArrayList<String>();
    247         for (String s : array) {
    248             if (p.and(b).test(s))
    249                 data.add(s);
    250         }
    251         return data;
    252     }
    253 
    254 
    255     /**
    256      * java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,
    257      * 后者称为后置条件
    258      */
    259     @Test
    260     public void test15() {
    261         String b = "5";
    262         demo15(b, s -> Integer.parseInt(s));
    263 
    264 
    265     }
    266 
    267     private void demo15(String b, Function<String, Integer> f) {
    268         Integer apply = f.apply(b);
    269         System.out.println(apply + 10);
    270 
    271     }
    272 
    273     @Test
    274     public void test16() {
    275         String b = "5";
    276         demo16(b,
    277                 s -> Integer.parseInt(s),
    278                 c -> c *= 10);
    279 
    280 
    281     }
    282 
    283     private void demo16(String b, Function<String, Integer> f, Function<Integer, Integer> c) {
    284         Integer apply = f.andThen(c).apply(b);
    285         System.out.println(apply);
    286 
    287     }
    288 
    289     /**
    290      * 请使用 Function 进行函数模型的拼接,按照顺序需要执行的多个函数操作为
    291      * 1. 将字符串截取数字年龄部分,得到字符串;
    292      * 2. 将上一步的字符串转换成为int类型的数字;
    293      * 3. 将上一步的int数字累加100,得到结果int数字。
    294      */
    295     @Test
    296     public void test17() {
    297         String nameAge="赵丽颖,18";
    298 
    299         int age = demo17(nameAge, s -> s.split(",")[1],
    300                 b -> Integer.parseInt(b),
    301                 n -> n += 100
    302         );
    303         System.out.println(age);
    304 
    305     }
    306     private int demo17(String b, Function<String, String> one, Function<String, Integer> two,Function<Integer, Integer> three) {
    307         return one.andThen(two).andThen(three).apply(b);
    308     }
    309 
    310 
    311 
    312 
    313 }
  • 相关阅读:
    java控制台输入
    冒泡排序
    选择排序
    Json数组去重
    HTTP状态码详解
    根据json对象的值替换json数组里的值
    用户中心页面
    正则表达式
    vue-router如何根据不同的用户给不同的权限
    vue2.0+element+node+webpack搭建的一个简单的后台管理界面
  • 原文地址:https://www.cnblogs.com/liushisaonian/p/11389040.html
Copyright © 2011-2022 走看看