java8新特性(Lambda表达式,函数式接口)

Lambda表达式

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以
传递的代码(将代码像数据一样进行传递)。

- Lambda的使用:

  1. 格式
  •  -> :lambda操作符 或 箭头操作符
    
  •  ->左边:lambda形参列表 (其实就是接口中的抽象方法的形参列表)
    
  •  ->右边:lambda体 (其实就是重写的抽象方法的方法体)
    
  1. Lambda表达式的使用:(分为6种情况介绍)
  • 语法格式一:无参,无返回值
    
 public void test1(){
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我是Runnable");
            }
        };
        r1.run();
        System.out.println("*************");
        Runnable r2 = () -> System.out.println("我是Lambada中的Runnable");
        r2.run();




 public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("inside runnable using anonymous inner class");
            }
        }).start();

        new Thread(() -> System.out.println("inside runnable using a lambda")).start();

        Runnable r = () -> System.out.println("using a lambda as a variable");
        new Thread(r).start();
    }/
  • 语法格式二:Lambda 需要一个参数,但是没有返回值,Consumer也是函数式接口中的一个
    
 public void test2(){
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("我的世界");
        System.out.println("**********************");

        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("我的世界从此很美");

    }
  • 语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”
    
 public void test3(){
        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("我的世界从此很美");
        System.out.println("****************");
        Consumer<String> con2 = (s) -> {
            System.out.println(s);
        };
        con2.accept("我的世界从此很美");
    }
  • 语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略
    
public void test4(){
        Consumer<String> con1 = (s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");

        System.out.println("*******************");

        Consumer<String> con2 = s -> {
            System.out.println(s);
        };
        con2.accept("一个是听得人当真了,一个是说的人当真了");
    }
  • 语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值
    
 public void test5(){

        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return o1.compareTo(o2);
            }
        };

        System.out.println(com1.compare(12,21));

        System.out.println("*****************************");
        Comparator<Integer> com2 = (o1,o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };

        System.out.println(com2.compare(12,6));


    }
  • 语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略
    
public void test6(){

        Comparator<Integer> com1 = (o1,o2) -> {
            return o1.compareTo(o2);
        };

        System.out.println(com1.compare(12,6));

        System.out.println("*****************************");

        Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);

        System.out.println(com2.compare(12,21));

    }

总结:
->左边:lambda形参列表的参数类型可以省略(类型推断);如果lambda形参列表只有一个参数,其一对()也可以省略

->右边:lambda体应该使用一对{}包裹;如果lambda体只有一条执行语句(可能是return语句),省略这一对{}和return关键字

函数式接口

  1. Lambda表达式的本质:作为函数式接口的实例
  2. 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
  3. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。
  • Lambda 就是为函数式接口服务的			
    

Java中内置4大函数接口
在这里插入图片描述

1.消费型接口

Consumer:消费型接口 单一抽象方法为:void accept(T t);

方法描述
void accept(T t)对给定的参数执行此操作
default Consumer andThen(Consumer<? super T> after)返回一个组合的 Consumer ,按顺序执行该操作,然后执行 after操作(用于函数复合)
  • 作用:消费某个对象**(传入一个泛型参数,不返回任何值)**

  • 举例:forEach: Iterable接口的foeEach方法 需要传入Consumer,大部分集合类都实现了该接口,用于返回Iterator对象进行迭代。

​ java.util.function包还定义了其他三种Consumer的基本变体(用于处理基本数据类型),以及一种双参数形式,BiConsumer接口的accept方法传入两个泛型参数,这两个泛型参数应为不同的类型。

接口单一抽象方法
IntConsumervoid accept(int x)
DoubleConsumervoid accept(double x)
LongConsumervoid accept(long x)
BiConsumervoid accept(T t,U u)
@Test
public void test1(){
        happy(1000,(x) -> System.out.println("需要消费" + x + "元!"));
    }
//这个就是不用lambda表达式的写法
public void test1(){
   happy(1000, new IntConsumer() {
       @Override
       public void accept(int x) {
           System.out.println("需要消费" + x + "元!");
       }
   });
    //首先我定义了一个happy方法,里面有2个参数,一个为int,一个为
    //消费型接口(传入一个值无返回值)当我在test1调用的时候就相当于我传入了一个值为X,
    //返回了一个输出语句,而根据我的happy方法可以得知我传入的值是我
    //第一个参数money,所以这个输出就是 需要消费1000元!
    public void happy(int money, IntConsumer con){
        con.accept(money);
    }
    //方便理解我们把原始方法,就相当于我们创建了一个实例,只是用Lambda
    //表达式的方式把他进行输出。
   happy(1000, new IntConsumer() {
            @Override
            public void accept(int x) {
                System.out.println("需要消费" + x + "元!");
            }
        });

2.供给型接口

Supplier:供给型接口 T get();

方法描述
T get()获得结果
  • 作用:创建一个对象(工厂类)(不传入参数,返回一个值)
  • 举例:Optional.orElseGet(Supplier<? extends T>):当this对象为null,就通过传入supplier创建一个T返回。(Optional类是一种容器对象,要么包装值,要么为空)

其他Supplier接口:(返回基本数据类型的数据)

接口单一抽象方法
IntSupplierint getAsInt()
DoubleSupplierdouble getAsDouble(double x)
LongSupplierlong getAsLong(long x)
BooleanSupplierboolean getAsBoolean(T t,U u)
 // 产生指定个数的整数,并放入集合中
    @Test
    public void test2(){
    //就想到与我产生了一个随机数,然后一共10次,存入的就是我lambda表达式返回的值。然后相当于存入为list里面的值就是我产生的值,和上面的方法类似下同
        List<Integer> numList = getNumList(10,() -> (int)(Math.random() * 100));

        for (Integer num:numList){
            System.out.println(num);
        }
    }
	//首先我定义了一个getNumList一个方法,里面2个参数,一个是int,一个是supplier接口,创建一个List,把生成的num个元素存入一个list中。
	//我传入值为空,返回一个值
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for(int i = 0;i<num;i++){
            Integer n = sup.get();
            list.add(n);
        }
        return  list;
    }

3.函数式接口

Function<T,R>:函数型接口 R apply(T t);

方法描述
default Function<T,V> andThen(Function<? super R,? extends V> after)返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果(先执行当前对象的apply方法,再执行after对象的方法)。
R apply(T t)将此函数应用于给定的参数。
default Function<V,R> compose(Function<? super V,? extends T> before)返回一个组合函数,首先将 before函数应用于其输入,然后将此函数应用于结果(先执行before对象的apply,再执行当前对象的apply,将两个执行逻辑串起来)。
static Function<T,T> identity()返回一个总是返回其输入参数的函数。
  • 作用:实现一个“一元函数”,即传入一个值经过函数的计算返回另一个值。(传入一个参数,返回一个值)
  public String strHandler(String str, Function<String,String> fun){
        return fun.apply(str);
    }

    @Test
    public void test3(){
        String newStr = strHandler("\t\t\t dfns;f ",(x) -> x.trim());
        System.out.println(newStr);
    }

其他Function接口(BiFunction接口定义了两个泛型输入类型和一个泛型输出类型)

接口单一抽象方法
IntFunctionR apply(int value)
DoubleFunctionR apply(double value)
LongFunctionR apply(long value)
ToIntFunctionint applyAsInt(T value)
ToDoubleFunctiondouble applyAsDouble(T value)
ToLongFunctionLong applyAsLong(T value)
DoubleToIntFunctionint applyAsInt(double value)
DoubleToLongFunctionLong applyAsLong(double value)
IntToDoubleFunctiondouble applyAsDouble(int value)
IntToLongFunctionlong applyAsLong(int value)
LongToDoubleFunctiondouble applyAsDouble(long value)
LongToIntFunctionint applyAsInt(long value)
BiFunctionR apply(T t, U u)

4.断言型接口

Predicate:断言型接口 单一抽象方法: boolean test(T t);

  • 作用:判断对象是否符合某个条件**(传入一个参数,返回一个布尔值)**
  • 举例:主要用于流的筛选。给定一个包含若干项的流,Stream接口的filter方法传入一个Predicate并返回一个新的流,它仅包含满足给定谓词的项。
方法描述
default Predicate and(Predicate<? super T> other)接收一个Predicate类型,也就是将传入的条件和当前条件以并且的关系过滤数据。
static Predicate isEqual(Object targetRef)返回根据 Objects.equals(Object, Object)测试两个参数是否相等的谓词。
default Predicate negate()返回表示此谓词的逻辑否定的谓词。
default Predicate or(Predicate<? super T> other)接收一个Predicate类型,将传入的条件和当前的条件以或者的关系过滤数据。
boolean test(T t)在给定的参数上评估这个谓词
  public List<String> filterStr(List<String> list, Predicate<String> pre){
        List<String> strList = new ArrayList<>();
        for(String str:list){
            if(pre.test(str)){
                strList.add(str);
            }
        }
        return strList;
    }

    @Test
    public void test4(){
        List<String> mystr = Arrays.asList("Hello","nihao","lambda","my");
        List<String> str1 = filterStr(mystr,(s) -> s.length() > 3);
        for (String str:str1 ){
            System.out.println(str);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值