Lambda的使用与实战
简介
(下面的简介也可以自己百度,一般进来的都是想知道怎么去用,所以这里主要也是重点在用法与实战上)
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
Lambda表达式还增强了集合库。 Java SE 8添加了lambda表达式。 在本文中,我们将从简单到复杂的示例中见认识lambda表达式。
环境准备
如果还没有安装Java 8,那么你应该先安装才能使用lambda。 像NetBeans 和IntelliJ IDEA 一类的工具和IDE就支持Java
8特性,包括lambda表达式和其他特性。
android studio中使用lambda方法见: android
studio中使用lambda
Lambda表达式的语法
基本语法:
(方法参数) -> 返回值
或
(方法参数) ->{ 方法内的语句; }
Lambda 简单与漂亮的案例
//没用使用lambda 的代码
ArrayList<String> strs = new ArrayList<>();
Collections.sort(strs, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
下面是使用了lambda后的效果
//4行代码只需要1句代码就搞定 Collections.sort(strs, String::compareTo);
Lambda 开始学习
上面的案例在后面会介绍到的.
为了更好的学习lambda 语法,我自己定义了一些接口,实现内部类,如下:
/**
* @Des: 内部方法带1个参数 , 不带返回值
*/
public interface IParmas1<A> {
void call(A a);
}
/**
* @Des: 内部方法带2个参数 , 不带返回值
*/
public interface IParmas2<A, B> {
void call(A a, B b);
}
/**
* @Des: 内部方法带2个参数 , 带返回值
*/
public interface IParmas2AndReturn<A, B, R> {
R call(A a, B b);
}
设置接口的监听,实现内部类
//不带返回值内部类,1个参数Demo
public void setOnIParmas1Listener(IParmas1 ipamr) {
}
//不带返回值内部类,2个参数Demo
public void setOnIParmas2Listener(IParmas2 ipamr) {
}
//带返回值内部类,2个参数Demo
public void setOnIParmas2AndReturnListener(IParmas2AndReturn ipamr) {
}
//配合demo1测试
public void demo1Test(Object o) {
}
//配合demo2测试
public void demo2Test(Object o1, Object o2) {
}
Lambda 双冒号(::)的使用
lambda 还有一个很屌的写法,看得我都觉得轻飘飘的feel都有了,
才发现原来java代码可以这么单纯的,来看看吧,我也是看到这个写法后才喜欢上lambda的.
那就是 lambda的双冒号(::)写法,lambda 双冒号写法前提条件是,方法接收的值是参数原值,没有拼接其他数据,
额,不明白是吧,开始我也是云里雾里,接着看下面解释吧:
1.这是订阅IParmas1 接口的一个监听.
setOnIParmas1Listener(IParmas1 ipamr)
2.在{@link IParmas1} 接口中定义的方法参数(A a),也就是Object.
void call(A a);
3.因此在接收内部类方法参数,也就是demo1Test(Object o),该方法的参数也是obj
demo1Test(Object o)
4.这样条件下就可以直接把下面的,案例1,写成带双冒号lambda 语法了
setOnIParmas1Listener(this::demo1Test); //(案例1的lambda写法)
多参数双冒号写法,见demo2的案例2.
Demo1 - 双冒号
//TODO 案例1,方法内部实现使用统一参数类型 原始写法
setOnIParmas1Listener(new IParmas1() {
@Override
public void call(Object o) {
ParmasImpl.this.demo1Test(o);
}
});
//lambda 写法
setOnIParmas1Listener(this::demo1Test);
//TODO 案例2,不带返回值 原始写法
setOnIParmas1Listener(new IParmas1() {
@Override
public void call(Object s) {
ParmasImpl.this.demo2();
}
});
// 不带返回值的lambda写法
setOnIParmas1Listener(s -> demo2());
Lambda 匿名内部类的使用
使用lambda 来美化匿名内部类的高度,看起来简单又优雅
lambda 会直接把整个内部类隐藏,只留下形参,而且有一点要注意,内部类使用lambda,
前提是,该内部类只有一个内部方法,如果有两个或以上则使用不了lambda语法:
1. 空参数 写法: () -> 内部类方法的实现.
2. 1参数(String) 写法: s -> 内部类方法的实现.
需要注意的是当参数为Void时,写法与有1个参数的一样
3. 2个参数(String,int) 写法: (s,i) -> 内部类方法的实现.
lambda的 内部类写法与泛型没有太大关系,但是也要注意器参数是否被引用.
如果引用的话,其实lambda 是不推荐使用表达式的,但是也可以用,就是在用
的时候,他会自动将类型转换成Object
如写法1中: s 和 i 现在其实是 obj类型
写法1:
setOnIParmas2Listener((s, i) -> {
System.out.println(s + "-----" + i);
});
写法2:当然也可声明类型
而且声明参数类型,只有参数在两个或以上才可以,一个参数是不可以声明的.
setOnIParmas2Listener((Object s,Object i) -> {
System.out.println(s + "-----" + i);
});
Demo2 - 匿名内部类
//TODO 案例1: 原始代码
setOnIParmas2Listener(new IParmas2<String, Integer>() {
@Override
public void call(String s, Integer i) {
System.out.println(s + "-----" + i);
}
});
//使用lambda
//因为上面其实是确定了类型的,被sout引用了,但是如果强制使用lambda的话
//会出现方法参数自动转向默认obj类型
setOnIParmas2Listener((s,i)-> System.out.println(s + "-----" + i));
//TODO 案例2:多参数使用 lambda双冒号
setOnIParmas2Listener(new IParmas2() {
@Override
public void call(Object o1, Object o2) {
ParmasImpl.this.demo2Test(o1, o2);
}
});
//使用lambda
setOnIParmas2Listener(this::demo2Test);
Lambda 方法带返回值的使用
在有返回值的时候有两种情况,下面使用带两个参数的内部方法来示范
1.内部方法直接返回,只有一个实现(方法/语句)
(s,i) -> null;
其实这个写法就跟返回值是void的一样,只是void返回值方法内实现一个(方法/语句)而已,
如demo1的案例2,中的lambda写法.
s -> demo2()
2.内部方法返回, 2个以上实现(方法/语句)
(s,i) -> {
System.out.println("带了一个sout的实现");
return null;
};
Demo2R - 带返回值
//TODO 带返回值的原始方法
setOnIParmas2AndReturnListener(new IParmas2AndReturn<String, Integer, Double>() {
@Override
public Double call(String s, Integer i) {
System.out.println("带了一个sout的实现");
return null;
}
});
//使用lambda 写法
setOnIParmas2AndReturnListener((s, i) -> {
System.out.println("带了一个sout的实现");
return null;
});
实际代码中实战用法
在上面demo 中已经说过了lambda 的一些常用方法,
下面是在实际中 对集合数据排序时的用法:
首先我们分析下Collections.sort(); 功能中参数内部类方法.
内部类Comparator ,默认内部方法compare(s1,s2)参数类型是String,带返回值int.
这样我们心里就大概知道lambda 该怎么去写或者这样写表达是上面意思.
//没用使用lambda 的代码
ArrayList<String> strs = new ArrayList<>();
Collections.sort(strs, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
//使用lambda 语法后,简单好看
/**
* this::demo1Test 与 String::compareTo 区别
*
* 表达的就是当前类下的demo1Test(obj,obj)方法,
* 其实你如果直接引用compareTo 方法也是可以的,那你就不可以用this了,
* 而是使用String 对象,因此compareTo 在String 对象内.
*/
// 1.1 使用匿名内部类根据values 排序 strs
Collections.sort(strs, this::demoTest);
// 1.2 使用匿名内部类根据values 排序 strs
Collections.sort(strs, String::compareTo);
// 2 使用lambda根据values 排序 strs
Comparator<String> sortByName = (s1, s2) -> (s1.compareTo(s2));
Collections.sort(strs, sortByName);
// 3 也可以采用声明形参的写法:
Collections.sort(strs, (String s1, String s2) -> (s1.compareTo(s2)));
下面是demoTest(String,String)的方法
/**
* 提出比较的方法出来,方便lambda的双冒号写法调用
*/
private int demo1Test(String s1, String s2) {
return s1.compareTo(s2);
}
demo代码:
Lambda的使用与实战的更多相关文章
- 读书笔记,《Java 8实战》,第三章,Lambda表达式
第一节,Lambda管中窥豹 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式,它没有名称,但它有参数列表.函数主题和返回值. 本节介绍了Lambda表达式的语法,它包括 ...
- Java 8 实战 P1 Fundamentals
目录 Chapter 1. Java 8: why should you care? Chapter 2. Passing code with behavior parameterization Ch ...
- Lambda实战(多练习)
import org.junit.Test; import java.math.BigDecimal; import java.time.LocalDate; import java.util.*; ...
- 乐字节-Java8核心特性实战之Lambda表达式
大家好,小乐又来给大家分享Java8核心特性了,上一篇文章是<乐字节|Java8核心实战-接口默认方法>,这次就来讲Java8核心特征之Lambda表达式. Java8 引入Lambda表 ...
- 行为参数化与lambda表达式 - 读《Java 8实战》
零. 概述 第一部分:1~3章 主要讲了行为参数化和Lambda表达式 第二部分:4~7章 主要讲了流的应用,包括流与集合差异,流的操作,收集器,注的并行执行 第三部分:8~12章 主要讲了怎样用Ja ...
- java8实战二------lambda表达式和函数式接口,简单就好
一.Lambda 可以把Lambda表达式理解为简洁地i表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还是一个可以抛出的异常列表. 听上去,跟我们用的匿名类,匿名 ...
- Java8 Lambda表达式实战之方法引用(一)
方法的引用 方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用 方法 ...
- 《JAVA8实战》读书笔记之传递方法和传递lambda
传递方法: 假设 你有一个Apple类,它 有一个getColor方法,还有一个变量inventory保存着一个Apples的列表.你可能想要选出所 有的绿苹果,并返回一个列表.通常我们用筛选(fil ...
- Java8实战Lambda和Stram API学习
public class Trader{ private String name; private String city; public Trader(String n, St ...
随机推荐
- Ajax相关——get请求和post请求的区别
一.完整的URL由以下几部分组成: scheme:通信协议,常用的有:http/ftp. host:主机,服务器(计算机)域名或IP地址 port:端口,整数,可选,省略时使用默认端口,http的默认 ...
- jmeter录制APP时不能登录的问题
问题描述: 录制APP时,其他一切挺顺利的,但在登录的时候提示"服务器发生未知错误,请稍后重试".一开始以为是接口问题,用python脚本调用了下,是可以登录的,排除接口问题.百度 ...
- 关于java的Synchronized,你可能需要知道这些(上)
对于使用java同学,synchronized是再熟悉不过了.synchronized是实现线程同步的基本手段,然而底层实现还是通过锁机制来保证,对于被synchronized修饰的区域每次只有一个线 ...
- MySQL 字符串连接CONCAT()函数
MySQL字符串连接函数 使用方法:CONCAT(str1,str2,-) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. 注意:如果所有参数均为非二进制字符串, ...
- Docker镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去. 通常 Union FS 有两个用途, 一方面可以实 ...
- Redis和nosql简介,api调用;Redis数据功能(String类型的数据处理);List数据结构(及Java调用处理);Hash数据结构;Set数据结构功能;sortedSet(有序集合)数
1.Redis和nosql简介,api调用 14.1/ nosql介绍 NoSQL:一类新出现的数据库(not only sql),它的特点: 1. 不支持SQL语法 2. 存储结构跟传统关系型数 ...
- 计算机网络之动态主机配置协议DHCP
为了将软件协议做成通用的和便于移植,协议软件的编写者不会把所有细节都固定在源代码中,而是把协议软件参数化,这就使得在很多台计算机上使用同一个经过编译的二进制代码成为可能. 一台计算机和另一台计算机的区 ...
- SKSpriteNode对象初始化在iPhone 6 plus中显示不正确的分析及解决
一个SpriteKit项目在其他设备上运行都无问题(无论是真机或是模拟器),但是在iPhone6 Plus上会出现精灵对象纹理被过度放大的现象: 从上图中大家可以看到无论是主角或是道具球都过大了. 看 ...
- Hadoop介绍
是适合大数据的分布式存储与计算平台,用java编写的开源系统,能够安排在大规模的计算机平台上,从而长进计算效率:由 HDFS.MapReduce.HBase.Hive 和 ZooKeeper等成员组成 ...
- x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...