JDK8 新特性 Lambda表达式
1.java8中Lambda表达式基础语法:
(x,y) -> {}
左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型;
中间是一个jdk8新定义的箭头符号;
右侧是一个大括号,在括号内编写抽象方法的实现内容,有参时,可直接使用左侧括号中的对应参数,与正常方法的方法体相同;
使用方式:实现只有一个抽象方法的接口时会自行匹配到该方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码(代码实现为单行时可去掉大括号{})
示例:
@Test
public void test() {
//输入一个数,与100比较大小 //实现方式1 匿名内部类:
Comparable<Integer> comparable1 = new Comparable<Integer>() {
@Override
public int compareTo(Integer o) {
return Integer.compare(o, 100);
}
};
comparable1.compareTo(2); //实现方式2 Lambda表达式:实现只有一个抽象方法的Comparable接口时会自行匹配到compareTo方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码
Comparable<Integer> comparable2 = (x) -> Integer.compare(x, 100);
comparable2.compareTo(2);
}
2.Lambda表达式的函数式编程需要函数式接口(有且只有一个抽象方法的接口)的支持,为了防止使用Lambda表达式时都必须手动添加接口,Java8内置了四大核心函数式接口:
/**
* Java8内置的四大核心函数式接口
*
* Consumer<T> :消费型接口
* void acept(T t);
*
* Supplier<T> :供给型接口
* T get();
*
* Function<T,R> :函数型接口
* R apply(T t);
*
* Predicate<T> :断言型接口
* boolean test(T t);
*/
public static void main(String[] args) {
//内置函数式接口使用示例 //消费型接口Consumer,输入一个参数,对其进行打印输出
Consumer<String> consumer = (x) -> System.out.println(x);
//打印字符串
consumer.accept("hehe"); //供给型接口Supplier,返回指定字符串
Supplier<String> supplier = () -> "Hello world!";
//获取字符串
supplier.get(); //函数型接口Function,输入字符串,返回字符串长度
Function<String, Integer> function = (x) -> x.length();
//获取字符串长度
function.apply("Hello world!"); //断言型接口Predicate,输入数字,判断是否大于0
Predicate<Integer> predicate = (x) -> x > 0;
//获取判断结果
predicate.test(10);
}
除了这四个接口外还有其他多参数的子接口,自行查找。
3.某些情况下要实现的业务部分已有方法实现,可直接引用该方法,此时可使用Lambda表达式中的方法引用: /**
* 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”
* 可以理解为方法引用是lambda表达式的另外一种表达形式
*
* 主要有三种语法格式:
*
* 对象::实例方法名
*
* 类::静态方法名
*
* 类::实例方法名
*/
方法引用注意点:被引用的方法的参数和返回值必须和要实现的抽象方法的参数和返回值一致
//引用out对象的打印输出方法作为Consumer接口accept方法的具体实现
Consumer<String> consumer1 = System.out::println;
consumer1.accept("hehe"); //lambda表达式常用方式
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
//方法引用:类::实例方法(方法传入参数是两个参数,且第一个参数作为方法调用对象,第二个参数作为调用的方法的参数)
BiPredicate<String, String> bp2 = String::equals;
4.构造器引用:通过函数式接口实例化类时可进行构造器引用
注意点:引用到的是与函数式接口中的方法参数个数及类型相同的构造器
//lambda表达式常用方式
Supplier<Passenger> supplier1 = () -> new Passenger();
//构造器引用:通过类型推断,引用无参构造器
Supplier<Passenger> supplier2 = Passenger::new;
//lambda表达式常用方式
BiFunction<String, String, Passenger> function1 = (x, y) -> new Passenger(x, y);
//构造器引用:通过类型推断,引用有两个String参数的构造器
BiFunction<String, String, Passenger> function2 = Passenger::new;
5.数组引用:
//lambda表达式常用方式
Function<Integer, String[]> fun1 = (x) -> new String[x];
String[] strs1 = fun1.apply(10);
//数组引用
Function<Integer, String[]> fun2 = String[]::new;
String[] strs2 = fun2.apply(10);
6.Stream流的应用
Stream的使用步骤:
1 创建Stream对象
2 执行中间操作
3 执行终止操作
1)Stream对象的创建方式:
/**
* Stream的使用:
* 1 创建Stream对象
* 2 中间操作
* 3 终止操作
*/
public static void main(String[] args) {
//stream对象获取方式:
String[] strings = {"1", "2", "3", "4"}; //方式1:数组获取stream对象
Stream<String> stream1 = Arrays.stream(strings); //方式2:集合获取stream对象
List<String> list = Arrays.asList(strings);
Stream<String> stream2 = list.stream(); //方式3:Stream静态方法of获取stream对象
Stream<String> stream3 = Stream.of(strings); //方式4:创建无限流(seed起始值,重复无限次执行的方法)
//无限流1:迭代
Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
//无限流2:生成
Stream<Double> stream5 = Stream.generate(() -> Math.random());
}
2)Stream常用中间操作方法:
//Stream常用方法(链式方法,从上往下执行,下一个方法进行处理的对象是上一个方法处理后的结果)
Arrays.stream(new Integer[]{1, 63, 3, 7, 11, 54, 34})
//过滤器,传入一个Predicate断言型接口实现,Stream会进行内部遍历,将保留断言返回true的元素(此处过滤保留值大于4的元素)
.filter(x -> x > 4)
//截断流,只获取前n个元素(此处获取满足过滤器条件的前2个元素)
.limit(5)
//跳过元素,跳过前n个元素,获取后面的元素,若流中的元素不足n个,则返回一个空流,与limit互补(此处取除第一个元素外的元素)
.skip(1)
//映射,对流内元素进行处理,可以是转换类型、获取属性值等等,传入一个Function函数型接口实现(此处对流内元素全部加5)
.map(x -> x + 5)
//自然排序(按照Comparable默认排序,此处为Integer从小到大排序)
.sorted()
//定制排序(按照Comparator自定义排序,此处处理为Integer从大到小排序)
.sorted((x, y) -> -Integer.compare(x, y))
//终止操作,遍历流内元素,传入一个Consumer消费型接口实现(此处简单对流内元素进行打印输出)
.forEach(System.out::println);
3)Stream常用终止操作方法:
//终止操作
Integer[] integers = {1, 63, 3, 7, 11, 54, 34};
List<Integer> list = Arrays.asList(integers); //匹配所有元素,传入一个Predicate断言型接口实现,当所有元素都满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b1 = list.stream().allMatch(x -> x > 0); //匹配元素,传入一个Predicate断言型接口实现,当有至少一个元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b2 = list.stream().anyMatch(x -> x > 0); //无匹配元素,传入一个Predicate断言型接口实现,没有元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b3 = list.stream().noneMatch(x -> x > 0); //匹配第一个元素
Optional<Integer> o4 = list.stream().findFirst(); //匹配任意一个元素
Optional<Integer> o5 = list.stream().findAny(); //获取流中元素个数
long l6 = list.stream().count(); //获取流中满足条件的最小值
Optional<Integer> min = list.stream().min(Integer::compare);
System.out.println("min:" + min.get()); //获取流中满足条件的最大值
Optional<Integer> max = list.stream().max(Integer::compare);
System.out.println("max:" + max.get()); //归约(将identity作为起始x,第一个元素作为y,计算结果再作为x与下一个元素进行计算,得出计算结果)
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
//归约(未设置起始x,因此有可能空指针,因此返回类型为Optional)
Optional<Integer> reduce1 = list.stream().reduce(Integer::sum); //收集(将流转换为其他形式,接受一个Collector接口实现,用于给Stream中元素做汇总的方法)
List<Integer> collect = list.stream().collect(Collectors.toList());
//转为hashset
HashSet<Integer> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new));
//取平均值
Double collect2 = list.stream().collect(Collectors.averagingInt((x) -> x));
System.out.println("avg:" + collect2);
//求和
Double collect3 = list.stream().collect(Collectors.summingDouble(x -> x));
System.out.println("sum:" + collect3);
待续。。。
JDK8 新特性 Lambda表达式的更多相关文章
- 大数据之路week06--day03(jdk8新特性 Lambda表达式)
为什么使用Lambda表达式?(做为初学者接触这个新的语法,会很懵逼,说道理,我在接触到这一块的时候,语法规则我看到了也很懵逼,因为这个和逻辑的关系不是很大,但就是作为一种新的语法出现,一时间很难接受 ...
- 乐字节-Java8新特性-Lambda表达式
上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...
- Java8新特性-Lambda表达式是什么?
目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...
- Java 8 新特性 - Lambda表达式
Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...
- C#10新特性-lambda 表达式和方法组的改进
C# 10 中对Lambda的语法和类型进行了多项改进: 1. Lambda自然类型 Lambda 表达式现在有时具有"自然"类型. 这意味着编译器通常可以推断出 lambda 表 ...
- jdk8的新特性 Lambda表达式
很多同学一开始接触Java8可能对Java8 Lambda表达式有点陌生. //这是一个普通的集合 List<Employee> list = em.selectEmployeeByLog ...
- JDK8的新特性——Lambda表达式
JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运用,甚至不被开发者所熟知. ...
- Java8新特性: lambda 表达式介绍
一.lambda 表达式介绍 lambda 表达式是 Java 8 的一个新特性,可以取代大部分的匿名内部类,简化了匿名委托的使用,让你让代码更加简洁,优雅. 比较官方的定义是这样的: lambda ...
- java8新特性——Lambda表达式
上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...
随机推荐
- tiny-Spring【2】逐步step分析-新加入特性
tiny-Spring是黄亿华大佬自己写的一个集合IOC和AOP于一身的一种轻量级[教学用]Spring框架,它的github库地址为:https://github.com/code4craft/ti ...
- 在论坛中出现的比较难的sql问题:9(触发器专题 插入数据自动更新表数据)
原文:在论坛中出现的比较难的sql问题:9(触发器专题 插入数据自动更新表数据) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所 ...
- 基于Docker的Kafka部署
一 准备 1.1 安装docker-dompose #部署 sudo curl -L "https://github.com/docker/compose/releases/download ...
- 监控神器-普罗米修斯Prometheus的安装
搬砖党的福音:普罗米修斯-监控神器 功能: 在业务层用作埋点系统 Prometheus支持多种语言(Go,java,python,ruby官方提供客户端,其他语言有第三方开源客户端).我们可以通过客户 ...
- JavaScript指定日期格式化
formatDataToString:function (dates, formats) { var o = { "M+": dates.getMonth() + 1, //月份 ...
- /sockjs-node/info 报错问题
首先 sockjs-node 确实是维持全双工通信用的,关键在于为什么要有这个东西,其实其作用就是保证我们在改完代码重新编译之后,能够通知浏览器重新加载变更结果(我也是因为之前都可以改完代码之后浏览器 ...
- Go 缓冲信道
缓冲信道 语法结构:cap为容量 ch := make(chan type, cap) 缓冲信道支持len()和cap(). 只能向缓冲信道发送容量以内的数据. 只能接收缓冲信道长度以内的数据. 缓冲 ...
- JS实现数组去重(重复元素保留一个)
1.遍历数组法 它是最简单的数组去重方法(indexOf方法) 实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中: var arr=[2,8,5, ...
- nginx的so_keepalive和timeout相关小计
KeepAlive 这里的keepalive是TCP的探活机制: [root@ ~]# sysctl -a |grep tcp_keepalive net.ipv4.tcp_keepalive_tim ...
- GC案例
FGC----jmap -histo:live导致 线上某服务的老年代配置了CMS,但却在gc.log发现连续Full GC的问题.JVM参数配置如下: -XX:+UseCMSInitiatingOc ...