首页IT科技java8 (jdk 1.8) 新特性——Lambda

java8 (jdk 1.8) 新特性——Lambda

时间2025-05-03 18:49:59分类IT科技浏览3638
导读:java8 (jdk 1.8 新特性 ——初步认识...

java8 (jdk 1.8) 新特性 ——初步认识

1. 什么是lambda?

目前已知的是           ,有个箭头->

说一大段官方话                 ,也没有任何意义

我们直接看代码:

之前我们创建线程是这样的

用lambda:

Runnable run2 = () -> System.out.println("run           。                 。      。     。                 。            。"); run2.run();

是不是感觉特别离谱      ,看不懂

别急           ,还有更离谱的

很常见的一个例子                 ,比较两个整数的大小

之前是这样写的

Comparator<Integer> myCom = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; int compare = myCom.compare(12, 20); int compare1 = myCom.compare(20, 12); int compare2 = myCom.compare(20, 20); System.out.println(compare); System.out.println(compare1); System.out.println(compare2); }

用lambda:

Comparator<Integer> myCom = (o1, o2) -> Integer.compare(o1, o2); int compare = myCom.compare(12, 20); int compare1 = myCom.compare(20, 12); int compare2 = myCom.compare(20, 20); System.out.println(compare); System.out.println(compare1); System.out.println(compare2);

  甚至还可以这样 (这个是方法引用)

Comparator<Integer> myCom = Integer::compare; int compare = myCom.compare(12, 20); int compare1 = myCom.compare(20, 12); int compare2 = myCom.compare(20, 20); System.out.println(compare); System.out.println(compare1); System.out.println(compare2);

第一个数比第二个数

大 :返回 1

小:返回 -1

相等:返回 0

刚接触是不是黑人问号      ,这是什么玩意

很好     ,到这                 ,你认识到了lambda 一个缺点           ,可阅读性差     ,优点 代码简洁

小结:看到 -> lambda 看到 : :方法引用

2. lamdba 语法

基本语法

1. 箭头操作符 -> 或者叫做lambda 操作符

2. 箭头操作符将lambda 表达式拆分成两部分

左侧:Lambda 表达式的参数列表

右侧:Lambda 表达式中所需执行的功能 , 即 Lambda 体

3.语法格式

语法格式1:无参数                 ,无返回值

() -> system.out.println("Hello Lambda")

前边线程的那个例子就是

语法格式2:有一个参数 无返回值

(x)-> System.out.println(x);

若只有一个参数可以省略不写

x-> System.out.println(x);

之前的写法           ,没有使用lambda

Consumer<String> consumer = new Consumer<String>() { @Override public void accept(String s) { System.out.println("输出的值:"+s); } }; consumer.accept("今天不想emo了");

使用lambda

Consumer<String> consumer = s -> System.out.println("输出的值:"+s); consumer.accept("今天不想emo了");

语法格式3:有两个以上参数 ,并且lambda体有多条语句                 ,有返回值

Comparator<Integer> myCom = (o1, o2) -> { System.out.println("其他语句"); return Integer.compare(o1, o2); };

语法格式4 lambda体中只有一条语句                 ,return 和 大括号都可以省略不写

Comparator<Integer> com =(x,y)-> Integer.compare(x,y);

  有没有发现所有的参数,都没有参数类型           ,之前我们写函数的时候可是要带上参数类型的

语法格式5 lambda表达式参数列表的数据类型可以省略不写                 ,因为JVM编译器通过上下文编译推断出数据类型——类型推断

4.函数式接口

不管上面哪一种语法格式      ,lambda都是需要函数式接口的支持

函数式接口:接口中只有一个抽象方法的接口 称为函数式接口

可以使用一个注解@FunctionalInterface 修饰,可以检查是否是函数式接口

我们可以看看Runnable 接口 的源码

完成的接口类代码如下

/* * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms / package java.lang; /** * The <code>Runnable</code> interface should be implemented by any * class whose instances are intended to be executed by a thread. The * class must define a method of no arguments called <code>run</code>. * <p> * This interface is designed to provide a common protocol for objects that * wish to execute code while they are active. For example, * <code>Runnable</code> is implemented by class <code>Thread</code>. * Being active simply means that a thread has been started and has not * yet been stopped. * <p> * In addition, <code>Runnable</code> provides the means for a class to be * active while not subclassing <code>Thread</code>. A class that implements * <code>Runnable</code> can run without subclassing <code>Thread</code> * by instantiating a <code>Thread</code> instance and passing itself in * as the target. In most cases, the <code>Runnable</code> interface should * be used if you are only planning to override the <code>run()</code> * method and no other <code>Thread</code> methods. * This is important because classes should not be subclassed * unless the programmer intends on modifying or enhancing the fundamental * behavior of the class. * * @author Arthur van Hoff * @see java.lang.Thread * @see java.util.concurrent.Callable * @since JDK1.0 */ @FunctionalInterface public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the objects * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }

可以看到这里面就只有一个实现           ,有一个注解@FunctionalInterface                  ,说明它就是一个函数式接口      ,就可以进行lambda简写

来看 Comparator 也是一样 有@FunctionalInterface注解

这里可能就会有疑问     ,这边明明是有两个抽象方法                 ,怎么是函数式接口呢?

别急 !!可以看到这边的注释, 说明这个equals 是 重写了超类 的 equals,本质上是对object 的重写           ,官方定义这样的抽象方法是不会被定义到 抽象接口数的      ,因此实际上只有一个抽象方法

我们自己可以试着定义 函数式接口                 ,很简单

package com.test1.demo; @FunctionalInterface public interface MyFunc { void method(); }

好了           ,如果,写两个抽象接口会怎样?

可以看到注解报错了                 ,所以注解用来校验作用就在这

重申一遍                 ,函数式接口:接口中只有一个抽象方法的接口 称为函数式接口

注解只是拿来校验的,方便我们一看就知道这是一函数式接口类           ,不然还得数个数                 ,验证一下是不是只有一个

现在我也重写equals ,可以看到并没有报错

5. java8 中内置四大核心函数式接口

Consumer<T> 消费型接口

//Consumer 消费型接口 @Test public void testConsumer() { cosumer(1000, (m) -> System.out.println("星期一" + m)); // 星期一1000.0 } public void cosumer(double m, Consumer<Double> con) { con.accept(m); }

供给型接口 supplier<T>

@Test public void testSupplier() { List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100)); for (Integer integer : numList) { System.out.println(integer); //100 以内10位随机整数 } } // 需求:产生指定个数的整数放入集合中 public List<Integer> getNumList(int num, Supplier<Integer> su) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < num; i++) { Integer integer = su.get(); list.add(integer); } return list; }

Function<T,R> 函数型接口

@Test public void FunctioStr(){ String c = getFunction("sbjikss", str -> str.toUpperCase()); System.out.println(c); //SBJIKSS String sub = getFunction("sbjikss", str -> str.substring(2, 3)); System.out.println(sub);//j } public String getFunction( String str, Function<String,String> f) { return f.apply(str); }

断言型接口 Predicate<T>

public void tetPre(){ List<String> list = Arrays.asList("Hello","sss","xxxx","sjjss"); List<String> list1 = filterStr(list, (pre) -> pre.length() > 3); for (String s : list1) { System.out.println(s); // Hello xxxx sjjss } } //需求:将满足条件字符串放入集合中 public List<String> filterStr(List<String> old , Predicate<String> pre ){ List<String> newList = new ArrayList<>(); for (String str : old) { if (pre.test(str)){ newList.add(str); } } return newList; }

感谢阅读!!!

声明:本站所有文章      ,如无特殊说明或标注           ,均为本站原创发布     。任何个人或组织                 ,在未征得本站同意时      ,禁止复制           、盗用                 、采集      、发布本站内容到任何网站     、书籍等各类媒体平台                。如若本站内容侵犯了原著者的合法权益     ,可联系我们进行处理            。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
u盘中的文件变成了快捷方式怎么办(U盘文件都变成快捷方式了怎么办?怎么恢复?) enw文件怎么默认用软件打开(.env 文件)