Lambda表达式

为什么使用lambda表达式

Lambda表达式可以简化我们的代码,使我们只需要关注主要的代码就可以。

//测试用的实体类

public class Employee {

    private String name;
private Integer age;
private double salary; public Employee() {
} public Employee(String name, Integer age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
}
//定义要操作的集合数据
List<Employee> employees = Arrays.asList( new Employee("张三",18,3000),
new Employee("李四",18,3000),
new Employee("张三",45,8700),
new Employee("王五",26,4500),
new Employee("麻子",30,2700),
new Employee("田七",15,200) );
//需求找出年龄大于20的员工

---------------最常规的操作--------

//过滤方法
public List<Employee> filterEmployee(List<Employee> employees){ ArrayList<Employee> list = new ArrayList<>();
for (Employee employee : employees) {
if(employee.getAge() > 20){
list.add(employee);
}
}
return list;
} //测试方法
@Test
public void test1(){
List<Employee> employees = filterEmployee(this.employees); for (Employee employee : employees) {
System.out.println(employee);
}
} //Employee{name='张三', age=45, salary=8700.0}
//Employee{name='王五', age=26, salary=4500.0}
//Employee{name='麻子', age=30, salary=2700.0} -------------第二种写法----------(策略模式) 1、先定义一个接口 public interface MyPredicate<T> { public boolean test(T t); } 2、定义过滤类实现我们定义的接口
public class FilterEmployeeByAge implements MyPredicate<Employee>{
@Override
public boolean test(Employee employee) { return employee.getAge()>20;
}
} 3、同样定义过滤方法
//过滤方法
public List<Employee> filterEmployee(List<Employee> employees, Mypredicatre<Employee> mp){ ArrayList<Employee> list = new ArrayList<>();
for (Employee employee : employees) {
if(mp.test){
list.add(employee);
}
}
return list;
} 4、测试方法 @Test
public void test2(){
List<Employee> employees = filterEmployee(this.employees, new FilterEmployeeByAge()); for (Employee employee : employees) {
System.out.println(employee);
}
} //Employee{name='张三', age=45, salary=8700.0}
//Employee{name='王五', age=26, salary=4500.0}
//Employee{name='麻子', age=30, salary=2700.0} -----------上面的方法每过滤不同的条件都要实现一个接口,不是很友好---------我们可以使用匿名内部类 @Test
public void test3(){
List<Employee> employees = filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getAge() > 20;
}
}); -----------------匿名内部类可以使用lambda表达式简化----------
@Test
public void test4(){
List<Employee> employees = filterEmployee(this.employees, (e) -> e.getAge() > 20); for (Employee employee : employees) {
System.out.println(employee);
}
}

lambda表达式需要函数式接口支持。

函数式接口:只有一个方法的接口,可以用注解@FunctionalInterface修饰接口

语法格式:

  • 无参数,无返回值 ()->System.out.println("hello word")
    @Test
public void test(){
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
};
//------------------lambda-----------------------------
Runnable r1 = ()-> System.out.println("hello world");
}
  • 有一个参数,无返回值 (x)-> System.out.println(x) (有一个参数小括号可以不写)
    @Test
public void test2(){
Consumer<String> con = (x)-> System.out.println(x);
//Consumer<String> con = x-> System.out.println(x);
con.accept("hello world");
}
  • 有两个参数,且有返回值 (有多条语句,必须使用{})
    @Test
public void test3(){
Comparator<Integer> com = (x,y)->{
System.out.println("函数式接口");
return Integer.compare(x,y);
};
}
  • 有两个参数,且有返回值,语句只有一条 (return 和{} 可以省略)
    @Test
public void test4(){
Comparator<Integer> com = (x,y)->Integer.compare(x,y);
}
  • lambda参数列表的数据类型可以省略不用写(类型推断)(要写都得写,不能写一个,一个不写)

java8中4大核心接口

Consumer : 消费型接口

​ void accept(T t);

    @Test
public void test4(){
happy(1000,(m) -> System.out.println("你消费了:"+m+"元"));
} public void happy(double money, Consumer<Double> con){
con.accept(money);
}

Supplier : 供给型接口

​ T get();

    @Test
//获取随机数
public void test5() {
List<Integer> numList = getNumList(5, () -> (int) (Math.random() * 10));
System.out.println(numList.toString());
}
//产生整数集合
public List<Integer> getNumList(int num, Supplier<Integer> sup) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}

Function<T,R>: 函数式接口

​ R apply(T t);

    @Test
public void test6(){
String str = strHandle("hello world", (s) -> s.substring(2, 5));
System.out.println(str);
}
//对字符串进行处理返回一个字符串
public String strHandle(String str, Function<String,String> fun){
return fun.apply(str);
}

Predicate: 断言型接口

​ boolean test(T t);

    @Test
public void test7(){
List<String> strings = Arrays.asList("hello", "world", "qw", "das", "s", "sadui");
List<String> str = filterStr(strings, (s) -> s.length() > 3);
System.out.println(str.toString());
}
//对字符串数组进行过滤
public List<String> filterStr(List<String> str, Predicate<String> pre){
ArrayList<String> list = new ArrayList<>(); for (String s : str) {
if(pre.test(s)){
list.add(s);
}
}
return list;
}

方法引用: 如果lambda体中的内容方法已经实现我们可以使用方法引用。

​ lambda表达式的另一种表现形式,

主要有三种语法格式:

Lambda体中方法的返回值要与实例方法返回值类型一致

  • 对象::实例方法名

@Test
public void test8(){
Consumer<String> con = (s) -> System.out.println(s); Consumer<String> con1 = System.out::println; PrintStream ps = System.out;
Consumer<String> con2 = ps::println; Employee emp = new Employee();
Supplier<Integer> sup = () -> emp.getAge();
Integer age = sup.get(); Supplier<Integer> sup1 = emp::getAge();
Integer age1 = sup1.get(); }
  • 类::静态方法名
    @Test
public void test9(){
Comparator<Integer> com = (x,y)-> Integer.compare(x,y); Comparator<Integer> com1 = Integer::compare; }
  • 类::实例方法名

    第一个参数是实例方法的调用者,第二参数是实例方法的参数才可以使用

    @Test
public void test10(){
BiPredicate<String,String> pre = (x,y)-> x.equals(y); BiPredicate<String,String> pre1 = String::equals; }

构造器引用:

className::new

​ 需要调用的构造器函数列表要与函数式接口中的抽象方法的参数列表保持一致

	@Test
public void test1(){ Supplier<Employee> sup = () -> new Employee(); //调用的是无参构造器
Supplier<Employee> sup1 = Employee::new; //调用的是带有一个参数的构造器
Function<Integer,Employee> fun = Employee::new; }

数组引用:

Type[]::new

	@Test
public void test1(){ Function<Integer,String[]> fun = (x)-> new String[x]; Function<Integer,String[]> fun1 = String[]::new; }

lambda表达式的学习的更多相关文章

  1. C++11 里lambda表达式的学习

    最近看到很多关于C++11的文档,有些是我不怎么用到,所以就略过去了,但是lambda表达式还是比较常用的,其实最开始学习python的时候就觉得lambda这个比较高级,为什么C++这么弱.果然C+ ...

  2. 【Java】Java8新增的Lambda表达式_学习笔记

    一.Lambda表达式可以简化创建匿名内部类对象 1.不需要new XXX(){}这种繁琐代码. 2.不需要指出重写的方法名. 3.不要给出重写的方法的返回值类型. 4.Lambda相当于一个匿名方法 ...

  3. Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)

    代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...

  4. C#中匿名委托以及Lambda表达式的学习笔记

    一. C#从1.0到4.0, 随着Linq,泛型的支持,代码越来越简单优雅 , , , , , , , , , }; IEnumerable< select n; newNums = newNu ...

  5. 【Java学习笔记之三十一】详解Java8 lambda表达式

    Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...

  6. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  7. 深入浅出 Java 8 Lambda 表达式

    摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...

  8. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  9. jdk8 lambda表达式总结

    Java8 lambda表达式10个示例   1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnab ...

随机推荐

  1. 【九度OJ】题目1441:人见人爱 A ^ B 解题报告

    [九度OJ]题目1441:人见人爱 A ^ B 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1441 题目描述: 求A^B ...

  2. 1110 距离之和最小 V3

    1110 距离之和最小 V3 基准时间限制:1 秒 空间限制:131072 KB X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * ...

  3. 常见分布式唯一ID生成策略

    方法一: 用数据库的 auto_increment 来生成 优点: 此方法使用数据库原有的功能,所以相对简单 能够保证唯一性 能够保证递增性 id 之间的步长是固定且可自定义的 缺点: 可用性难以保证 ...

  4. Reflection 基础知识(一)

    反射机制的定义 反射通常指在程序在运行时能够获取自身的信息. 静态语言反射 在java中使用反射的一个例子 Class<?> clazz = Class.forName("com ...

  5. Java初学者作业——编写Java程序,简单判断“王者荣耀”英雄收到攻击后是否死亡

    返回本章节 返回作业目录 需求说明: 判断"王者荣耀"中英雄受到攻击后是否死亡? 计算"王者荣耀"中怪物攻击英雄的伤害,做出英雄死亡的判断. 如果英雄受到过量伤 ...

  6. MongoDB分片集群机制及原理

    1. MongoDB常见的部署架构 * 单机版 * 复制集 * 分片集群 2. 为什么要使用分片集群 * 数据容量日益增大,访问性能日渐下降,怎么破? * 新品上线异常火爆,如何支撑更多用户并发? * ...

  7. CSS 基础 选择器的使用汇总

    1.后代选择器 html 结构 <div class='father'> <p>小哥哥 小姐姐</p> <div> <p>小帅锅</p ...

  8. dos 之 for循环(小“病毒”)

    需求: 1.自动在D盘下创建test2019文件夹: 2.自动在test2019下面创建100个文件,并写入"这是文件几的内容!": 3.自动打开100个CMD运行窗口(保持打开状 ...

  9. python 设计模式:单例模型

    一.单例模型简介 代码的设计模式共有25种,不同的应用场景应用不同的设计模式,从而达到简化代码.利于扩展.提高性能等目的.本文简述Python实现的单例模式场景.简而言之,单例模式的应用场景是一个类对 ...

  10. SCryptPasswordEncoder 单向加密 --- 心得

    1.前言 * BCryptPasswordEncoder相关知识:* 用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的s ...