暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java函数式接口

Hello 帅帅 2021-02-05
592

FunctionalInterface注解

Java 8中专门为函数式接口引入了一个新的注解:@FunctionalInterface 。该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。

     @FunctionalInterface
    public interface MyFunction {
    int add(int a, int b);
    }

    通过lambda表达式使用该接口:

       public class Main {
      public static void main(String[] args) {
      doing((int a, int b) -> 2 * (a + b) , 1, 2);
      }

      public static void doing(MyFunction m, int a, int b) {
      System.out.println(m.add(a, b));
      }
      }

      Lambda的延迟执行:

      例:在参数l=1时,输出三个字符串相加的结果

      传统写法:无论参数l是什么,都会执行字符串相加

         public class Main3 {
        public static void main(String[] args) {
        String s1 = "hello ";
        String s2 = "world";
        String s3 = "!";
        log(1, s1 + s2 + s3);
        }

        private static void log(int l, String s) {
        if (l == 1) {
        System.out.println(s);
        }
        }
        }

        lambda表达式写法:

           public class Main2 {
          public static void main(String[] args) {
          String s1 = "hello ";
          String s2 = "world";
          String s3 = "!";
          log(1, () -> s1 + s2 + s3);
          }

          private static void log(int l, Log log) {
          if (l == 1) {
          System.out.println("执行");
          System.out.println(log.mylog());
          }
          }
          }

          @FunctionalInterface
          public interface Log {
          String mylog();
          }

          在参数l=1时才会执行三个字符串相加。(用匿名内部类方法也会这样执行)

          Lambda作为参数和返回值


          常用函数式接口

          Supplier接口

          抽象方法:get

          java.util.function.Supplier<T>
          接口仅包含一个无参的方法:T get()
          。用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。

          主要用于执行lambda表达式,无法传参,可获取返回值

          源码:

             @FunctionalInterface
            public interface Supplier<T> {
            T get();
            }

            使用样例:

               public class Main4 {
              public static void main(String[] args) {
              String A = "Hello";
              String B = "World";
              Supplier<String> fun = () -> A + B;
              System.out.println(fun.get());
              }
              }

              Consumer接口

              源码:

                 @FunctionalInterface
                public interface Consumer<T> {

                void accept(T t);

                default Consumer<T> andThen(Consumer<? super T> after) {
                //保证after不为null,否则会报错
                Objects.requireNonNull(after);
                return (T t) -> { accept(t); after.accept(t); };
                }
                }

                抽象方法:accept

                主要用于传入参数执行lambda表达式,但无返回值

                   public class Main5 {
                  public static void main(String[] args) {
                  Consumer<String> fun1 = (str) -> System.out.println(str);
                  fun1.accept("aaa");
                  }
                  }

                  默认方法:andThen

                    public class Main5 {
                    public static void main(String[] args) {
                    String[] array = {"Xiao WenWen", "Big WenWen", "Middle WenWen"};
                    format(s -> System.out.print("姓" + s.split(" ")[0]), s -> System.out.println("名" + s.split(" ")[1]), array);
                    }


                    private static void format(Consumer<String> c1,Consumer<String> c2,String[] arr){
                    for (String s : arr) {
                    //将参数s传入,先执行c1,再执行c2,可进行链式编程
                    c1.andThen(c2).accept(s);
                    }
                    }
                    }

                    Predicate接口

                    判断传入参数是否满足条件,满足返回true,否则为false

                    源码:

                      @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);
                      }


                      @SuppressWarnings("unchecked")
                      static <T> Predicate<T> not(Predicate<? super T> target) {
                      Objects.requireNonNull(target);
                      return (Predicate<T>)target.negate();
                      }
                      }

                      抽象方法:test

                      判断字符串中有没有字母e

                        public class Main6 {
                        public static void main(String[] args) {
                        Predicate<String> p = s -> s.contains("e");
                        String[] str = {"hello", "my", "dear", "world"};
                        ArrayList<Boolean> arr = new ArrayList<>();
                        for (String s : str) {
                        boolean b = p.test(s);
                        arr.add(b);
                        }
                        System.out.println(arr);
                        }
                        }

                        输出:

                          [true, false, true, true]

                          默认方法:and

                          判断字符串中有没有字母e和l

                            private static void demo2() {
                            Predicate<String> p = s -> s.contains("e");
                            Predicate<String> p1 = s -> s.contains("l");
                            String[] str = {"hello", "my", "dear", "world"};
                            ArrayList<Boolean> arr = new ArrayList<>();
                            for (String s : str) {
                            boolean b = p.and(p1).test(s);
                            arr.add(b);
                            }
                            System.out.println(arr);
                            }

                            输出:

                              [true, false, false, false]

                              默认方法:or

                              判断字符串中有没有字母e或l

                                private static void demo3() {
                                Predicate<String> p = s -> s.contains("e");
                                Predicate<String> p1 = s -> s.contains("l");
                                String[] str = {"hello", "my", "dear", "world"};
                                ArrayList<Boolean> arr = new ArrayList<>();
                                for (String s : str) {
                                boolean b = p.or(p1).test(s);
                                arr.add(b);
                                }
                                System.out.println(arr);
                                }

                                输出:

                                  [true, false, true, true]

                                  默认方法:negate(取反)

                                  判断字符串中有没有字母e,有则返回false

                                    private static void demo4() {
                                    Predicate<String> p = s -> s.contains("e");
                                    String[] str = {"hello", "my", "dear", "world"};
                                    ArrayList<Boolean> arr = new ArrayList<>();
                                    for (String s : str) {
                                    boolean b = p.negate().test(s);
                                    arr.add(b);
                                    }
                                    System.out.println(arr);
                                    }

                                    输出:

                                      [false, true, false, true]

                                      静态方法:not

                                      not用于将原lambda表达时返回值取反

                                      判断字符串中有没有字母e,有则返回false

                                        private static void demo5() {
                                        Predicate<String> p1 = s -> s.contains("e");
                                        Predicate<String> p = Predicate.not(p1);
                                        String[] str = {"hello", "my", "dear", "world"};
                                        ArrayList<Boolean> arr = new ArrayList<>();
                                        for (String s : str) {
                                        boolean b = p.test(s);
                                        arr.add(b);
                                        }
                                        System.out.println(arr);
                                        }

                                        输出:

                                          [false, true, false, true]

                                          静态方法:isEqual

                                          isEqual方法用于判断两个参数是否相同

                                            private static void demo6() {
                                            System.out.print(Predicate.isEqual("aaaa").test("aaaa")+" ");
                                            System.out.print(Predicate.isEqual("aaaa").test("aa1a")+" ");
                                            System.out.println(Predicate.isEqual("aaaa").test("aa"+"aa"));
                                            }

                                            输出:

                                              true false true

                                              Function接口

                                                @FunctionalInterface
                                                public interface Function<T, R> {
                                                R apply(T t);


                                                default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
                                                Objects.requireNonNull(before);
                                                return (V v) -> apply(before.apply(v));
                                                }


                                                default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
                                                Objects.requireNonNull(after);
                                                return (T t) -> after.apply(apply(t));
                                                }


                                                static <T> Function<T, T> identity() {
                                                return t -> t;
                                                }
                                                }

                                                抽象方法:apply

                                                传入一个值,传出一个值

                                                  private static void demo1() {
                                                  Function<String, Integer> fun = (s) -> {
                                                  return Integer.parseInt("10");
                                                  };
                                                  Integer apply = fun.apply("10");
                                                  System.out.println(apply);
                                                  }

                                                  输出:

                                                    10

                                                    默认方法:andThen

                                                    先执行fun,再将fun的返回值传入fun1

                                                      private static void demo1() {
                                                      Function<String, Integer> fun = (s) -> {
                                                      return Integer.parseInt("10")+10;
                                                      };
                                                      Function<Integer, Integer> fun2 = (i) -> {
                                                      return i * 10;
                                                      };
                                                      Integer apply = fun.andThen(fun2).apply("10");
                                                      System.out.println(apply);
                                                      }

                                                      输出:

                                                         200

                                                        默认方法:compose

                                                           private static void demo2() {
                                                          Function<Integer, Integer> fun = (s) -> {
                                                          return s + 10;
                                                          };
                                                          Function<Integer, Integer> fun2 = (i) -> {
                                                          return i * 10;
                                                          };
                                                          Integer apply1 = fun.compose(fun2).apply(10);
                                                          System.out.println(apply1);
                                                          }

                                                          输出:

                                                             110

                                                            Stream流

                                                            Stream流遍历集合

                                                               private static void demo1() {
                                                              List<String> l = new ArrayList<>();
                                                              l.add("hello ");
                                                              l.add("my ");
                                                              l.add("dear ");
                                                              l.add("cute");
                                                              l.add("world");

                                                              Predicate<String> p=s -> !s.startsWith("h");
                                                              Predicate<String> p1=s -> s.length() >= 3;
                                                              Consumer<String> x= System.out::println;
                                                              l.stream().filter(p).filter(p1).forEach(x);
                                                              }

                                                              输出:

                                                                 my 
                                                                dear
                                                                cute
                                                                world

                                                                获取流方法

                                                                Collection获取流

                                                                调用.stream()方法

                                                                   private static void demo2() {
                                                                  List<String> list = new ArrayList<>();
                                                                  Stream<String> stream1 = list.stream();

                                                                  Set<String> set = new HashSet<>();
                                                                  Stream<String> stream2 = set.stream();
                                                                  }

                                                                  Map获取流

                                                                  • map.keySet().stream();

                                                                  • map.values().stream();

                                                                  • map.entrySet().stream();

                                                                     private static void demo3() {
                                                                    Map<String, String> map = new HashMap<>();
                                                                    Stream<String> keyStream = map.keySet().stream();
                                                                    Stream<String> valueStream = map.values().stream();
                                                                    Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
                                                                    }

                                                                    数组获取流

                                                                    Stream.of(array);

                                                                       private static void demo4() {
                                                                      String[] array = {"张无忌", "张翠山", "张三丰", "张一元"};
                                                                      Stream<String> stream = Stream.of(array);
                                                                      }

                                                                      流常用方法

                                                                      遍历:forEach

                                                                         private static void demo5() {
                                                                        List<String> l = new ArrayList<>();
                                                                        l.add("hello ");
                                                                        l.add("my ");
                                                                        l.add("dear ");
                                                                        l.add("cute");
                                                                        l.add("world");
                                                                        Consumer<String> x = System.out::println;
                                                                        l.stream().forEach(x);
                                                                        }

                                                                        过滤器:filter

                                                                           private static void demo1() {
                                                                          List<String> l = new ArrayList<>();
                                                                          l.add("hello ");
                                                                          l.add("my ");
                                                                          l.add("dear ");
                                                                          l.add("cute");
                                                                          l.add("world");

                                                                          Predicate<String> p = s -> !s.startsWith("h");
                                                                          Predicate<String> p1 = s -> s.length() >= 3;
                                                                          Consumer<String> x = System.out::println;
                                                                          l.stream().filter(p).filter(p1).forEach(x);
                                                                          }

                                                                          映射:map

                                                                             private static void demo6() {
                                                                            Stream<String> original = Stream.of("10", "12", "18");
                                                                            Stream<Integer> result = original.map(str-> Integer.parseInt(str));
                                                                            }

                                                                            计数:count

                                                                               private static void demo7() {
                                                                              Stream<String> original = Stream.of("10", "12", "18");
                                                                              long count = original.count();
                                                                              System.out.println(count);
                                                                              }

                                                                              取前几个:limit

                                                                                 private static void demo8() {
                                                                                Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
                                                                                Stream<String> result = original.limit(2);
                                                                                System.out.println(result);
                                                                                }

                                                                                跳过前几个:skip

                                                                                   private static void demo9() {
                                                                                  Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
                                                                                  Stream<String> result = original.skip(2);
                                                                                  result.forEach(System.out::println);
                                                                                  }

                                                                                  组合:concat

                                                                                     private static void demo10() {
                                                                                    Stream<String> streamA = Stream.of("张无忌");
                                                                                    Stream<String> streamB = Stream.of("张翠山");
                                                                                    Stream<String> result = Stream.concat(streamA, streamB);
                                                                                    result.forEach(System.out::println);
                                                                                    }

                                                                                    方法引用

                                                                                    双冒号::为引用运算符,而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么则可以通过双冒号来引用该方法作为Lambda的替代者。

                                                                                    通过对象名引用成员方法

                                                                                    Calculate:

                                                                                       public class Calculate {
                                                                                      int add(int a, int b) {
                                                                                      return a+b;
                                                                                      }
                                                                                      }

                                                                                      MyAdd:

                                                                                         @FunctionalInterface
                                                                                        public interface MyAdd {
                                                                                        int myadding(int a,int b);
                                                                                        }

                                                                                        例:

                                                                                           private static void demo1() {
                                                                                          Calculate c=new Calculate();
                                                                                          MyAdd ma=c::add;
                                                                                          int res = ma.myadding(1, 3);
                                                                                          System.out.println(res);//4
                                                                                          }

                                                                                          通过类名称引用静态方法

                                                                                             private static void demo2() {
                                                                                            MyAdd ma2=Math::max;
                                                                                            ma2.myadding(1,2);//2
                                                                                            }

                                                                                            通过super引用成员方法

                                                                                            MyFun:

                                                                                               @FunctionalInterface
                                                                                              public interface MyFun {
                                                                                              void say();
                                                                                              }

                                                                                              Father:

                                                                                                 public class Father {
                                                                                                public void sayHello() {
                                                                                                System.out.println("输出父类方法");
                                                                                                }
                                                                                                }

                                                                                                Son:

                                                                                                   public class Son extends Father {
                                                                                                  @Override
                                                                                                  public void sayHello() {
                                                                                                  MyFun mf = super::sayHello;
                                                                                                  mf.say();
                                                                                                  System.out.println("输出子类方法");
                                                                                                  }
                                                                                                  }
                                                                                                  private static void demo3() {
                                                                                                  Son s=new Son();
                                                                                                  s.sayHello();
                                                                                                  }

                                                                                                  通过this引用成员方法

                                                                                                     private void demo4() {
                                                                                                    MyFun mf = this::sayHello;
                                                                                                    mf.say();
                                                                                                    }

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

                                                                                                    类的构造器引用

                                                                                                    Person:

                                                                                                       public class Person {
                                                                                                      private String name;
                                                                                                      @Override
                                                                                                      public String toString() {
                                                                                                      return "Person{" +
                                                                                                      "name='" + name + '\'' +
                                                                                                      '}';
                                                                                                      }
                                                                                                      public Person(String name) {
                                                                                                      this.name = name;
                                                                                                      }
                                                                                                      }

                                                                                                      Builder:

                                                                                                         @FunctionalInterface
                                                                                                        public interface Builder {
                                                                                                        Person buildPerson(String name);
                                                                                                        }
                                                                                                        private static void demo5() {
                                                                                                        Builder b = Person::new;
                                                                                                        Person wenwen = b.buildPerson("wenwen");
                                                                                                        System.out.println(wenwen);
                                                                                                        }

                                                                                                        数组的构造器引用

                                                                                                        ArrayBuilder:

                                                                                                           @FunctionalInterface
                                                                                                          public interface ArrayBuilder {
                                                                                                          int[] buildArray(int length);
                                                                                                          }

                                                                                                          构造数组:

                                                                                                             private static void demo6() {
                                                                                                            ArrayBuilder ab = int[]::new;
                                                                                                            int[] ints = ab.buildArray(5);
                                                                                                            System.out.println(Arrays.toString(ints));
                                                                                                            }


                                                                                                            文章转载自Hello 帅帅,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                                                                            评论