50字范文,内容丰富有趣,生活中的好帮手!
50字范文 > java8新特性(Lambda表达式 函数式接口)

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

时间:2018-07-14 13:57:07

相关推荐

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

Lambda表达式,函数式接口

Lambda表达式函数式接口1.消费型接口2.供给型接口3.函数式接口4.断言型接口

Lambda表达式

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以

传递的代码(将代码像数据一样进行传递)。

- Lambda的使用:

格式

-> :lambda操作符 或 箭头操作符

->左边:lambda形参列表 (其实就是接口中的抽象方法的形参列表)

->右边:lambda体 (其实就是重写的抽象方法的方法体)

Lambda表达式的使用:(分为6种情况介绍)

语法格式一:无参,无返回值

public void test1(){Runnable r1 = new Runnable() {@Overridepublic 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() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic int compare(Integer o1, Integer o2) {System.out.println(o1);System.out.println(o2);return pareTo(o2);}};System.out.println(pare(12,21));System.out.println("*****************************");Comparator<Integer> com2 = (o1,o2) -> {System.out.println(o1);System.out.println(o2);return pareTo(o2);};System.out.println(pare(12,6));}

语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略

public void test6(){Comparator<Integer> com1 = (o1,o2) -> {return pareTo(o2);};System.out.println(pare(12,6));System.out.println("*****************************");Comparator<Integer> com2 = (o1,o2) -> pareTo(o2);System.out.println(pare(12,21));}

总结:

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

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

函数式接口

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

Lambda 就是为函数式接口服务的

Java中内置4大函数接口

1.消费型接口

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

作用:消费某个对象**(传入一个泛型参数,不返回任何值)**

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

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

@Testpublic void test1(){happy(1000,(x) -> System.out.println("需要消费" + x + "元!"));}//这个就是不用lambda表达式的写法public void test1(){happy(1000, new IntConsumer() {@Overridepublic 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() {@Overridepublic void accept(int x) {System.out.println("需要消费" + x + "元!");}});

2.供给型接口

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

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

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

// 产生指定个数的整数,并放入集合中@Testpublic 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);

作用:实现一个“一元函数”,即传入一个值经过函数的计算返回另一个值。(传入一个参数,返回一个值)

public String strHandler(String str, Function<String,String> fun){return fun.apply(str);}@Testpublic void test3(){String newStr = strHandler("\t\t\t dfns;f ",(x) -> x.trim());System.out.println(newStr);}

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

4.断言型接口

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

作用:判断对象是否符合某个条件**(传入一个参数,返回一个布尔值)**举例:主要用于流的筛选。给定一个包含若干项的流,Stream接口的filter方法传入一个Predicate并返回一个新的流,它仅包含满足给定谓词的项。

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。