Lambda表达式常用代码示例
Lambda表达式常用代码示例
2017-10-24
目录
1 Lambda表达式是什么
2 Lambda表达式语法
3 函数式接口是什么
3.1 常用函数式接口
4 Lambdas和Streams结合使用
4.1 使用forEach方法
4.2 使用过滤器filter方法
4.3 使用limit方法
4.4 使用sorted方法
4.5 使用map方法
4.6 使用parallelStream方法
4.7 使用summaryStatistics方法
参考
1 Lambda表达式是什么
返回
Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确。在Java中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface))。Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式就和方法一样,它提供了一个正常的参数列表(argument)和一个使用这些参数的主体(body)。
Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。
Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。
2 Lambda表达式语法
返回
Java 中的 Lambda 表达式通常使用 (argument) -> {body}
语法书写,例如:
(arg1, arg2...) -> { body } (type1 arg1, type2 arg2...) -> { body }
以下是一些 Lambda 表达式的例子:
(int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return 3.1415 };
Lambda表达式结构说明:
- 一个 Lambda 表达式可以有零个或多个参数
- 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
- 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
- 空圆括号代表参数集为空。例如:() -> 42
- 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
- Lambda 表达式的主体可包含零条或多条语句
- 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
- 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
3 函数式接口是什么
返回
函数式接口是只包含一个抽象方法声明的接口。
java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),相似地,ActionListener 接口也是一种函数式接口,我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。Runnable接口代码如下:
@FunctionalInterface public interface Runnable {public abstract void run(); }
每个 Lambda 表达式都能隐式地赋值给函数式接口。如下代码:
Runnable r = () -> System.out.println("hello world");
Runnable的Lambda表达式和匿名内部类的使用示例
![](/assets/blank.gif)
![](/assets/blank.gif)
public void sample01() {// 1.1使用匿名内部类new Thread(new Runnable() {@Overridepublic void run() {System.out.println("1.1 Hello world !");}}).start();// 1.2使用 lambda expressionnew Thread(() -> System.out.println("1.2 Hello world !")).start();// 2.1使用匿名内部类Runnable race1 = new Runnable() {@Overridepublic void run() {System.out.println("1.3 Hello world !");}};// 2.2使用 lambda expressionRunnable race2 = () -> System.out.println("1.4 Hello world !");// 直接调用 run 方法(没开新线程哦!) race1.run();race2.run();}
View Code
自定义函数式接口及Lambda表达式和匿名内部类的使用示例
WorkerInterface.java
![](/assets/blank.gif)
![](/assets/blank.gif)
//定义一个函数式接口 @FunctionalInterface public interface WorkerInterface {public void doSomeWork(); }
View Code
WorkerInterfaceTest.java
![](/assets/blank.gif)
![](/assets/blank.gif)
public class WorkerInterfaceTest {public static void main(String [] args) {//invoke doSomeWork using Annonymous classexecute(new WorkerInterface() {@Overridepublic void doSomeWork() {System.out.println("Worker invoked using Anonymous class");}});//invoke doSomeWork using Lambda expressionexecute( () -> System.out.println("Worker invoked using Lambda expression") );}public static void execute(WorkerInterface worker) {worker.doSomeWork();} }
View Code
3.1 常用函数式接口
Predicate、Function、Consumer、Supplier示例代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
//Predicate 接口只有一个参数,返回boolean类型。。Predicate<String> predicate = (s) -> s.length() > 3;System.out.println(predicate.test("foo")); // falsePredicate<Boolean> nonNull = Objects::nonNull; System.out.println(nonNull.test(false)); // true //Function 接口接受一个参数,返回一个结果,并附带了一些可以和其他函数组合的默认方法(compose, andThen) Function<String, Integer> toInteger = Integer::valueOf; System.out.println(toInteger.apply("123").getClass()); //class java.lang.Integer Function<String, String> backToString = toInteger.andThen(String::valueOf); System.out.println(backToString.apply("123").getClass()); //class java.lang.String //Consumer 接口接受一个参数,没有返回结果。 Consumer<Cat> greeter = (c) -> System.out.println("Hello, " + c.name); Cat cat=new Cat("Tom", 3); greeter.accept(cat); //Hello, Tom //Supplier接口没有参数,。 Supplier<Double> number = () -> Math.random(); System.out.println(number.get()); //0.8765252430762529
View Code
使用Lambdas排序集合
在Java中,Comparator 类被用来排序集合。
使用匿名内部类或Lambda表达式根据 name 排序 players:
![](/assets/blank.gif)
![](/assets/blank.gif)
String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer","Roger Federer", "Andy Murray", "Tomas Berdych", "Juan Martin Del Potro","Richard Gasquet", "John Isner"};// 1.1 使用匿名内部类根据 name 排序 playersArrays.sort(players, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return (s1.compareTo(s2));}});// 1.2 使用 lambda expression 排序 playersComparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));Arrays.sort(players, sortByName);// 1.3 也可以采用如下形式:Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
View Code
其他排序:
![](/assets/blank.gif)
![](/assets/blank.gif)
// 2.1 使用匿名内部类根据 surname 排序 playersArrays.sort(players, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));}});// 2.2 使用 lambda expression 排序,根据 surnameComparator<String> sortBySurname = (String s1, String s2) ->( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );Arrays.sort(players, sortBySurname);// 2.3 或者这样,怀疑原作者是不是想错了,括号好多...Arrays.sort(players, (String s1, String s2) ->( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) ));// 3.1 使用匿名内部类根据 name lenght 排序 playersArrays.sort(players, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return (s1.length() - s2.length());}});// 3.2 使用 lambda expression 排序,根据 name lenghtComparator<String> sortByNameLenght = (String s1, String s2) -> (s1.length() - s2.length());Arrays.sort(players, sortByNameLenght);// 3.3 or thisArrays.sort(players, (String s1, String s2) -> (s1.length() - s2.length()));// 4.1 使用匿名内部类排序 players, 根据最后一个字母Arrays.sort(players, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));}});// 4.2 使用 lambda expression 排序,根据最后一个字母Comparator<String> sortByLastLetter =(String s1, String s2) ->(s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));Arrays.sort(players, sortByLastLetter);// 4.3 or thisArrays.sort(players, (String s1, String s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));
View Code
4 Lambdas和Streams结合使用
返回
Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。
Person.java代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
public class Person {private String firstName;private String lastName;private String job;private String gender;private int salary;private int age;public Person(String firstName, String lastName, String job,String gender, int age, int salary) {this.setFirstName(firstName);this.setLastName(lastName);this.setGender(gender);this.setAge(age);this.setJob(job);this.setSalary(salary);}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
View Code
初始化Person代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
List<Person> javaProgrammers = new ArrayList<Person>() {{add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));}};List<Person> phpProgrammers = new ArrayList<Person>() {{add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));}};
View Code
4.1 使用forEach方法
使用forEach方法显示所有程序员姓名:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("所有程序员的姓名:");javaProgrammers.forEach((p) -> System.out.println(String.format("%s %s; ", p.getFirstName(), p.getLastName())));phpProgrammers.forEach((p) -> System.out.println(String.format("%s %s; ", p.getFirstName(), p.getLastName())));
View Code
ForEach代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
public interface Iterable<T> {default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}}...}
View Code
使用forEach方法,增加程序员的工资5%:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("给程序员加薪 5% :");Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());javaProgrammers.forEach(giveRaise);phpProgrammers.forEach(giveRaise);
View Code
4.2 使用过滤器filter方法
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("下面是月薪超过 $1,400 的PHP程序员:");phpProgrammers.stream().filter((p) -> (p.getSalary() > 1400)).forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));// 定义 filters Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);Predicate<Person> salaryFilter = (p) -> (p.getSalary() > 1400);Predicate<Person> genderFilter = (p) -> ("female".equals(p.getGender()));System.out.println("下面是年龄大于 25岁且月薪在$1,400以上的女PHP程序员:");phpProgrammers.stream().filter(ageFilter).filter(salaryFilter).filter(genderFilter).forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
View Code
4.3 使用limit方法
使用limit方法可以限制结果集的个数:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("最前面的3个 Java programmers:");javaProgrammers.stream().limit(3).forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));System.out.println("最前面的3个女性 Java programmers:");javaProgrammers.stream().filter(genderFilter).limit(3).forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
View Code
4.4 使用sorted方法
使用sorted方法进行排序:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("根据 name 排序,并显示前5个 Java programmers:");List<Person> sortedJavaProgrammers = javaProgrammers.stream().sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName()))).limit(5).collect(toList());sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));System.out.println("根据 salary 排序 Java programmers:");sortedJavaProgrammers = javaProgrammers.stream().sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) ).collect( toList() );sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
View Code
使用min和max方法:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("工资最低的 Java programmer:");Person pers = javaProgrammers.stream().min((p1, p2) -> (p1.getSalary() - p2.getSalary())).get();System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary());System.out.println("工资最高的 Java programmer:");Person person = javaProgrammers.stream().max((p, p2) -> (p.getSalary() - p2.getSalary())).get();System.out.printf("Name: %s %s; Salary: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary());
View Code
4.5 使用map方法
结合 map 方法,我们可以使用 collect 方法来将我们的结果集放到一个字符串,一个 Set 或一个TreeSet中:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("将 PHP programmers 的 first name 拼接成字符串:");String phpDevelopers = phpProgrammers.stream().map(Person::getFirstName).collect(joining(" ; ")); // 在进一步的操作中可以作为标记(token)System.out.println(phpDevelopers); //Jarrod ; Clarette ; Victor ; Tori ; Osborne ; Rosalind ; Fraser ; Quinn ; Alvin ; Evonne System.out.println("将 Java programmers 的 first name 存放到 Set:");Set<String> javaDevFirstName = javaProgrammers.stream().map(Person::getFirstName).collect(toSet());System.out.println(javaDevFirstName); //[Elsdon, Shawn, Palmer, Addison, Maude, Floyd, Vere, Tamsen, Jayden, Sindy] System.out.println("将 Java programmers 的 last name 存放到 TreeSet:");TreeSet<String> javaDevLastName = javaProgrammers.stream().map(Person::getLastName).collect(toCollection(TreeSet::new));System.out.println(javaDevLastName); //[Brittany, Corrina, Dene, Donny, Hervey, Jaimie, Jaycob, Jonie, Pam, Randall]
View Code
4.6 使用parallelStream方法
当需要为多核系统优化时,可以 parallelStream().forEach(),只是此时原有元素的次序没法保证,并行的情况下将改变串行时操作的行为:
![](/assets/blank.gif)
![](/assets/blank.gif)
System.out.println("计算付给 Java programmers 的所有money:");int totalSalary = javaProgrammers.parallelStream().mapToInt(p -> p.getSalary()).sum();
View Code
4.7 使用summaryStatistics方法
使用summaryStatistics方法获得stream 中元素的各种汇总数据:
![](/assets/blank.gif)
![](/assets/blank.gif)
//计算 count, min, max, sum, and average for numbersList<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();System.out.println("List中最大的数字 : " + stats.getMax());System.out.println("List中最小的数字 : " + stats.getMin());System.out.println("所有数字的总和 : " + stats.getSum());System.out.println("所有数字的平均值 : " + stats.getAverage());
View Code
参考
[1] 深入浅出 Java 8 Lambda 表达式
[2] Java中Lambda表达式的使用
[3] Java 8 中的 Streams API 详解
[4] Lambda 表达式讲解
Lambda表达式常用代码示例相关推荐
- Lambda 表达式基础理论与示例
Lambda 表达式基础理论与示例 Lambda 表达式,也可称为闭包,推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). 使用 Lam ...
- JDK8系列之Lambda表达式教程和示例
JDK8系列之Lambda表达式教程和示例 1.Lambada 表达式简介 Lambda 表达式是一种匿名函数,但对Java中的Lambda表达式而已并不完全正确,简单来说,Lambda表达式是一种没 ...
- java lambda例子_Java lambda 表达式常用示例
实体类 package com.lkb.java_lambda.dto; import lombok.Data; /** * @program: java_lambda * @description: ...
- java 拉姆表达式_Java8 lambda表达式10个示例
Java 8 lambda表达式示例 转自importNew 原文链接 例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现R ...
- Java 8 Lambda表达式10个示例【存】
PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...
- Db4o结合Linq、Lambda表达式的简单示例
大多数人接触Db4o的查询,都是从"样本查询"(Query by Example)开始的,这种查询方式简单但不方便,功能和性能也很受局限.以下是引自官方的样本查询示例: // re ...
- java中fileter用法,Java 8 使用Lambda表达式的FileFilter示例
java.io.FileFilter接口是一个功能接口,在java 8中由 在这个例子中,我们将展示如何使用lambda表达式在FileFilter中来列出子目录的名称. 文件:LambdaFileF ...
- Java8 Lambda表达式语法和示例
本文是对官方文档(https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)的概括总结,更详细的内容请看官方 ...
- LAMBDA表达式常用 (全)
这里主要是将数据库中的常用操作用LAMBDA表达式重新表示了下,用法不多,但相对较常用,等有时间了还会扩展,并将查询语句及LINQ到时也一并重新整理下: 1.select语句:books.Select ...
最新文章
- R语言ggplot2可视化水平条形图的标题(title)、副标题(subtitle)和图片说明信息(caption)左对齐实战
- mysql master-slave_mysql 同步 master-slave
- JAVA入门笔记·JAVA名词及环境搭建
- 【NLP】深度学习文本分类|模型代码技巧
- js控制页面刷新大全
- Palindrome Index
- php实现最简单的MVC框架实例教程
- 初学者python笔记(装饰器后篇:登陆验证)
- 【语音分析】基于matlab语音短时时域分析【含Matlab源码 559期】
- python中缀表达式转后缀表达式_中缀表达式转换成后缀表达式
- Oracle P6培训系列:10增加作业并估算工期
- redis过期策略有哪些?内存淘汰机制有哪些?
- 一碗糖水,生津又补气,最适合宝宝三伏天喝!
- 【每日爬虫】:利用线程池爬取百思不得姐段子
- 未来,你会反感虚拟现实沉浸式广告吗?
- Python学习:面向对象基础练习——士兵突击(代码演示) 及 身份运算符
- PAT_乙级_1006_筱筱
- 数据分析(1):对比分析法
- 选品指南:波兰市场什么最好卖?有哪些热门类目?
- Graccvs文件正文提取开发组件--文件内容搜索的利器
热门文章
- 支持透明窗口显示的webbrowser_支持十点触控!LG推出新透明OLED显示屏
- Mysql基础运维及复制架构——PRIT非完整恢复
- mysql两个表left join_mysql中两张表使用left join on 求差集
- oracle使用打开数据库文件,Oracle技术网—某个数据文件损坏,如何打开数据库
- 安装启动gui卡住_为什么Windows 10升级安装卡住了,原因在这
- android对应的java版本_Android Studio gradle插件版本和gradle版本对应关系
- c获取当前系统时间_Python系统:程序和进程
- Python爬虫==入门基础概念
- 数据结构之单链表(golang版)
- springboot项目打包运行