JavaSE笔记(函数式接口、Stream流、lambda表达式简化语法)

目录

函数式接口

注解

@FunctionalInterface

四个常用的函数式接口

Supplier

Consumer

Predicate

Function

Stream流

获得Stream流的方式

常用API

特殊的lambda表达式的简化语法

使用前提

使用方法

对象引用普通成员方法  

类引用静态方法 

引用构造方法 

引用数组的构造器 

 通过this引用成员方法 

通过super引用父类成员方法 

总结


函数式接口

注解

注释是给程序员看的,而注解会编译进JVM,比如@Override重写,如果重写的时候不加该注解,JVM将不会认为这是重写的。

@FunctionalInterface

函数式接口,必须要一个接口并且只包含一个抽象方法才能使用该注解,一般配合lambda表达式使用

四个常用的函数式接口

Supplier

  • 生产者接口,用来生产对象,T get()方法
public class Demo {
    public static void main(String[] args) {
        int number = 10;
        System.out.println(lambda(()->number*2));
    }
    public static int lambda(Supplier<Integer> s){
        return s.get();
    }
}

Consumer

  • 消费者接口,使用一个对象,void accept(T var1)方法
public class Demo {
    public static void main(String[] args) {
        int number = 10;
        lambda((t) -> System.out.println(t*2),number);
    }
    public static void lambda(Consumer<Integer> con,int n) {
        con.accept(n);
    }
}
  • Consumer<T> andThen(Consumer<? super T> after)方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        lambda(t -> System.out.println(t+1),t->System.out.println(t*2),number);
    }
    public static void lambda(Consumer<Integer> con1,Consumer<Integer> con2,int n) {
        con1.andThen(con2).accept(n);
        //等价于以下代码
//        con1.accept(n);
//        con2.accept(n);
    }
}

Predicate

  • 用于判断,boolean Test(T t)方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        int[] arr = {1,4,5,3,7,3,5,3,6};
        lambda(n->n>3,arr);
    }
    public static void lambda(Predicate<Integer> pre,int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if (pre.test(arr[i])) System.out.println(arr[i]);
        }
    }
}
  • Predicate<T> and(Predicate<? super T> other)方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        int[] arr = {1,4,5,3,7,3,5,3,6};
        lambda(n->n>3,n->n<8,arr);
    }
    public static void lambda(Predicate<Integer> pre1,Predicate<Integer> pre2,int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if (pre1.and(pre2).test(arr[i])) System.out.println(arr[i]);
            //等价于以下代码
//            if (pre1.test(arr[i])&& pre2.test(arr[i])) System.out.println(arr[i]);
        }
    }
}
  • Predicate<T> negate()方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        System.out.println(lambda(n->n>5,number));
    }
    public static boolean lambda(Predicate <Integer> pre,Integer number) {
        return pre.negate().test(number);
        //等价于以下代码
//        return !pre.test(number);
    }
}

Function

  • 用于格式转化,R apply(T t)方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        System.out.println(lambda(n->Integer.toString(n),number).getClass());
    }
    public static String lambda(Function<Integer,String> fun,Integer i) {
        return fun.apply(i);
    }
}
  • <V> Function<T,V> andThen(Function<? super R,? extends V> after) 方法
public class Demo {
    public static void main(String[] args) {
        Integer number = 10;
        System.out.println(lambda(i->Integer.toString(i),s->s.getBytes(),number).getClass());
    }
    public static byte[] lambda(Function<Integer,String> fun1,Function<String,byte[]> fun2,Integer i) {
        return fun1.andThen(fun2).apply(i);
        //等价于以下代码
//        return fun2.apply(fun1.apply(i));
    }
}

Stream流

Stream(I)用来操作集合的流,类似于工程的流水线

获得Stream流的方式

  • List获得Stream对象
    List<String> list = List.of("aaa","bbb","ccc");//快速生成一个不可变的集合对象
    Stream<String> stream = list.stream()
  • Set获得Stream对象
    Set<String> set = Set.of("aaa","bbb","ccc");
    Stream<String> stream = set.stream();
  •  Map获得Stream对象
    Map<String,Integer> map = Map.of("aaa",1,"bbb",2,"ccc",3);
    Stream<String> stream = map.keySet().stream();
    Stream<Integer> stream2 = map.values().stream();
    Stream<Map.Entry<String,Integer>> stream3 = map.entry().stream();
    
  • 数组获得Stream对象
    String[] arr = {"aaa","bbb","ccc"};
    Stream<String> stream = Arrays.stream(arr);
  •  直接将很多元素包装成Strean
    Stream<Integer> stream = Stream.of(5,3,8,3);

常用API

延迟方法:返回值还是Stream流

终结方法:返回值不是Stream流

返回值方法描述
voidforEach(Consumer<? extends T> action)对此流的每个元素进行遍历操作
Stream<T>filter(Predicate<? super T> predicate)返回按条件筛选过后的流
<R> Stream<R>map(Function<? super T,? extends R> mapper)返回将此流装换成另一个类型的流
Stream<T>limit(long maxSize)返回取前maxSize个元素的流
Stream<T>skip(long n)返回跳过(丢弃)n个元素的流
longcount()返回流中元素的数量
static<T> Stream<T>concat(Stream<? extends T> a,Stream<? extends T> b)返回一个a流拼接b流的流(a在前b在后)
Object[]toArray()返回包含此流中所有元素的数组
public static void main(String[] args) {
    List<String> list = List.of("a","bb","ccc","dddd","eeeee","ffffff");//快速生成一个不可变的集合对象
    Stream<String> stream = list.stream();
    //先筛选长度大于1的,再根据长度转化成Integer类型,再跳过一个,再取前三个,再遍历输出
    stream.filter(n->n.length()>1).map(n->n.length()).skip(1).limit(3).forEach(n-> System.out.println(n));
}

特殊的lambda表达式的简化语法

使用前提

  • 必须是lambda表达式
  • lambda表达式中只有一句代码
  • 在lambda表达式的方法参数,直接传递给lambda表达式内调用方法的参数

使用方法

对象引用普通成员方法  

对象::成员方法

n -> System.out.println(n)  可以简化成  System.out::println

class Koo{
    void printKoo( Object o){
        System.out.println(o);
    }
}
interface printFun{
    void print(Object o);
}
public class Demo {
    static void printMain(printFun pf,Object o){
        System.out.println("---------------");
        pf.print(o);
    }
    public static void main(String[] args) {
       Koo koo = new Koo();
        printMain(koo::printKoo,"aaaaa");
//        等价于以下代码
        printMain(n->koo.printKoo(n),"aaaaa");
//        等价于以下代码
        printMain(new printFun() {
          @Override
          public void print(Object o) {
             koo.printKoo(o);
          }
      }, "aaaaa");
    }
}

类引用静态方法 

类::静态方法

n -> Math.abs(n)  可以简化成  Math::abs

class Koo{
    static void printKoo( Object o){
        System.out.println(o);
    }
}
interface printFun{
    void print(Object o);
}
public class Demo {
    static void printMain(printFun pf,Object o){
        System.out.println("---------------");
        pf.print(o);
    }
    public static void main(String[] args) {
        printMain(Koo::printKoo, "aaaaa");
        //等价于以下代码
        printMain((n)->Koo.printKoo(n),"aaaaa");
        //等价于以下代码
        printMain(new printFun() {
            @Override
            public void print(Object o) {
                Koo.printKoo(o);
            }
        },"aaaaa");
    }
}

引用构造方法 

类::new 

n -> new String(n)  可以简化成  String::new

class Koo{
    Integer i;
    public Koo(Integer i) {
        this.i = i;
    }
}
interface creatFun{
    Koo create(Integer i);
}
public class Demo {
    public static void creatKoo(creatFun cre,Integer i){
        System.out.println(cre.create(i));
    }
    public static void main(String[] args) {
        creatKoo(Koo::new,10);
        //等价于以下代码
        creatKoo((i)-> new Koo(i),10);
        //等价于以下代码
        creatKoo(new creatFun() {
            @Override
            public Koo create(Integer i) {
                return new Koo(i);
            }
        },10);
    }
}

引用数组的构造器 

数组类型::new

(n) -> new int[n]  可以简化成  int[]::new

interface creatFun{
    int[] create(int len);
}
public class Demo {
    public static void creat(creatFun cre,int i){
        System.out.println(Arrays.toString(cre.create(i)));
    }
    public static void main(String[] args) {
        creat(int[]::new,10);
        //等价于以下代码
        creat(n -> new int[n],10);
        //等价于以下代码
        creat(new creatFun() {
            @Override
            public int[] create(int len) {
                return new int[len];
            }
        },10);
    }
}

 通过this引用成员方法 

this::方法

n -> this.method(n)  可以简化成  this::method

class Koo{
    void method1(){
        method2(this::method3,10);
        //等价于以下代码
        method2(i -> this.method3(i),10);
        //等价于以下代码
        method2(new creatFun() {
            @Override
            public void creat(int i) {
                new Koo.method3(i);
            }
        }, 10);
    }
    void method2(creatFun cre,int i){
        cre.creat(i);
    }
    void method3(int i){
        System.out.println(i+1);
    }
}
interface creatFun{
    void creat(int i);
}
public class Demo {
    public static void main(String[] args) {
        Koo koo = new Koo();
        koo.method1();
    }
}

通过super引用父类成员方法 

super::方法

n -> this.method(n)  可以简化成  super::method

class Poo{
    void method3(int i){
        System.out.println(i+2);
    }
}
class Koo extends Poo{
    void method1(){
        method2(super::method3,10);
        //等价于以下代码
        method2(i -> super.method3(i),10);
        //等价于以下代码
        method2(new creatFun() {
            @Override
            public void creat(int i) {
                new Poo().method3(i);
            }
        }, 10);
    }
    void method2(creatFun cre,int i){
        cre.creat(i);
    }
    void method3(int i){
        System.out.println(i+1);
    }
}
interface creatFun{
    void creat(int i);
}
public class Demo {
    public static void main(String[] args) {
        Koo koo = new Koo();
        koo.method1();
    }
}

总结

  • 四个常用的函数式接口,起码要了解他们当中的抽象方法
  • Stream流可以快速对集合进行一些操作,节省代码量
  • 特殊的lambda表达式简化方法有六种,可以不用,但是必须要看得懂
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值