博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的Java学习笔记-Lambda表达式
阅读量:3957 次
发布时间:2019-05-24

本文共 7792 字,大约阅读时间需要 25 分钟。

学习目标:

学会使用Lambda表达式及其相关操作


学习内容:

一.什么是Lambda表达式?

1.概念:

Lambda表达式,也可以成为闭包。是Java 8的一个重要新特性。

与匿名类相比,就是匿名方法,是一种把方法作为参数进行传递的编程思想。

2.使用示例:

import java.util.ArrayList;import java.util.List;import java.util.Random;//参考文章末尾的英雄类import charactor.Hero; public class TestLamdba {
public static void main(String[] args) {
Random r = new Random(); List
heros = new ArrayList
(); for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100))); } System.out.println("初始化后的集合:"); System.out.println(heros); System.out.println("使用匿名类的方式,筛选出 hp>100 && damange<50的英雄"); // 匿名类的正常写法 HeroChecker c1 = new HeroChecker() {
@Override public boolean test(Hero h) {
return (h.hp > 100 && h.damage < 50); } }; // 把new HeroChcekcer,方法名,方法返回类型信息去掉 // 只保留方法参数和方法体 // 参数和方法体之间加上符号 -> HeroChecker c2 = (Hero h) -> {
return h.hp > 100 && h.damage < 50; }; // 把return和{}去掉 HeroChecker c3 = (Hero h) -> h.hp > 100 && h.damage < 50; // 把 参数类型和圆括号去掉 HeroChecker c4 = h -> h.hp > 100 && h.damage < 50; // 把c4作为参数传递进去 filter(heros, c4); // 直接把表达式传递进去 filter(heros, h -> h.hp > 100 && h.damage < 50); } private static void filter(List
heros, HeroChecker checker) {
for (Hero hero : heros) {
if (checker.test(hero)) System.out.print(hero); } } }

3.lambda表达式的重要特征:

(1)可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

(2)可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

(3)可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

(4)可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

4.使用Lambda表达式的好处:

(1)使代码更简洁

(2)可以装逼

5.不好的地方:

Lambda比较适合用在简短的业务代码中,并不适合用在复杂的系统中,会加大维护成本。

(1) 可读性差:与啰嗦的但是清晰的匿名类代码结构比较起来,Lambda表达式一旦变得比较长,就难以理解

(2) 不便于调试:很难在Lambda表达式中增加调试信息,比如日志

(3) 版本支持:Lambda表达式在JDK8版本中才开始支持,如果系统使用的是以前的版本,考虑系统的稳定性等原因,而不愿意升级,那么就无法使用。

二.方法引用

1.引用静态方法:

import java.util.*;//参考文章末尾的英雄类import charactor.Hero;//lambda表达式引用静态方法public class test3 {
public static void main(String[] args) {
Random r =new Random(); List
heros = new ArrayList
(); for (int i = 0; i < 10; i++) {
//通过随机值实例化hero的hp和damage heros.add(new Hero("hero "+ i, r.nextInt(100), r.nextInt(100))); } //Comparator
c = new //lambda表达式引用静态方法 Collections.sort(heros,test3::maxMin); System.out.println("按照血量排序后的集合:"); System.out.println(heros); } public static int maxMin(Hero h1,Hero h2){
if(h1.hp>=h2.hp) return 1; else return -1; }}

2.引用对象方法:

import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Random;//参考文章末尾的英雄类import charactor.Hero;//lambda表达式引用对象方法public class test4 {
public static void main(String[] args) {
Random r =new Random(); List
heros = new ArrayList
(); for (int i = 0; i < 10; i++) {
//通过随机值实例化hero的hp和damage heros.add(new Hero("hero "+ i, r.nextInt(100), r.nextInt(100))); } //Comparator
c = new //lambda表达式引用对象方法 test4 t4 = new test4(); Collections.sort(heros,t4::maxMin); System.out.println("按照血量排序后的集合:"); System.out.println(heros); } public int maxMin(Hero h1,Hero h2){
if(h1.hp>=h2.hp) return 1; else return -1; }}

3.引用构造器:

import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.function.Supplier;//参考文章末尾的英雄类import charactor.Hero;//lambda表达式引用构造器public class test6 {
public static void main(String[] args) {
List
l; l = new ArrayList<>(); modify(l, "ArrayList"); l = new LinkedList<>(); modify(l, "LinkedList"); //lambda表达式引用构造器 List list1 = getList(ArrayList::new); modify(list1, "ArrayList"); } public static List getList(Supplier
s) {
return s.get(); } private static void modify(List
l, String type) {
int total = 100 * 1000; int index = total / 2; final int number = 5; //初始化 for (int i = 0; i < total; i++) {
l.add(number); } long start = System.currentTimeMillis(); for (int i = 0; i < total; i++) {
int n = l.get(index); n++; l.set(index, n); } long end = System.currentTimeMillis(); System.out.printf("%s总长度是%d,定位到第%d个数据,取出来,加1,再放回去%n 重复%d遍,总共耗时 %d 毫秒 %n", type, total, index, total, end - start); System.out.println(); }}

三.聚合操作

一.概念:

要了解聚合操作,首先要建立 Stream管道 的概念

*Stream 和Collection结构化的数据不一样,Stream是一系列的元素,就像是生产线上的罐头一样,一串串的出来。
*管道指的是一系列的聚合操作。

管道又分3个部分

*管道源:Collection切换成管道源很简单,调用stream()就行了。数组没有stream()方法,需要使用Arrays.stream(arr) //arr是数组名

*中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操作,并不会真正进行遍历。

中间操作比较多,主要分两类

对元素进行筛选:
filter 匹配
distinct 去除重复(根据equals判断)
sorted 自然排序
sorted(Comparator) 指定排序
limit 保留
skip 忽略
转换为其他形式的流
mapToDouble 转换为double的流
map 转换为任意类型的流

*结束操作:当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回, 结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断。

常见结束操作如下

forEach() 遍历每个元素
toArray() 转换为数组
min(Comparator) 取最小的元素
max(Comparator) 取最大的元素
count() 总数
findFirst() 第一个元素

: 这个Stream和I/O章节的InputStream,OutputStream是不一样的概念。

二.使用示例:

import java.util.ArrayList;import java.util.List;import java.util.Random;//参考文章末尾的英雄类import charactor.Hero;/*首选准备10个Hero对象,hp和damage都是随机数。分别用传统方式和聚合操作的方式,把hp第三高的英雄名称打印出来 */public class test7 {
public static void main(String[] args) {
Random random = new Random(); List
list = new ArrayList<>(); for (int i = 0; i < 10; i++) {
Hero h = new Hero(); h.name = "hero"+i; h.hp = random.nextInt(100); h.damage = random.nextInt(500); list.add(h); } /** * 我写的 //聚合遍历集合 list .stream() .forEach(h -> System.out.println(h)); //System.out.println(list); //聚合排序 Object[] heroes = list.stream().sorted((h1, h2)->h1.hp>h2.hp?1:-1).toArray(); System.out.println(heroes[heroes.length-3]); 我是个渣渣!*/ //别人写的的 String name =list .stream() .sorted((h1,h2)->h1.hp>h2.hp?-1:1) .skip(2) .map(h->h.getName()) .findFirst() .get(); System.out.println(name); }}

学习时间:

三小时

继续奋斗!

另:英雄类

public class Hero{
public String name; public float hp; public int damage; public String getName() {
return name; } public void setName(String name) {
this.name = name; } public float getHp() {
return hp; } public void setHp(float hp) {
this.hp = hp; } public int getDamage() {
return damage; } public void setDamage(int damage) {
this.damage = damage; } public Hero(){
} public Hero(String name) {
this.name =name; } public boolean matched(){
return this.hp>100 && this.damage<50; } public Hero(String name,float hp, int damage) {
this.name =name; this.hp = hp; this.damage = damage; } public int compareHero(Hero h){
return hp>=h.hp?-1:1; } public String toString() {
return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n"; }}

转载地址:http://xdozi.baihongyu.com/

你可能感兴趣的文章
asii码表
查看>>
<读书笔记>WebUsage Mining:Discovery and Applications of Usage Patterns from Web Data
查看>>
并查集(Disjoint Sets)
查看>>
在Linux下安装MATLAB
查看>>
readme
查看>>
微服务概念
查看>>
数据库分库分表
查看>>
hibernate inverse 和cascade讲解
查看>>
建模工具Rose的学习
查看>>
javascript ajax提出异步请求
查看>>
Hibernate 中的 QBC
查看>>
解快局域网共享问题
查看>>
xp常用命令
查看>>
java 加密解密
查看>>
xp 忘记密码
查看>>
xp 忘记密码
查看>>
java 过滤器
查看>>
java 过滤器
查看>>
as发送邮件
查看>>
AJAX应用之注册用户即时检测
查看>>