JAVA基础知识|lambda与stream

lambda与stream是java8中比较重要两个新特性,lambda表达式采用一种简洁的语法定义代码块,允许我们将行为传递到函数中。之前我们想将行为传递到函数中,仅有的选择是使用匿名内部类,现在我们可以使用lambda表达式替代匿名内部类。在学习lambda表达式之前,建议各位看官先去学习一下匿名内部类(JAVA基础知识|内部类)。

stream提供了很多有用的api,方便了我们对集合的操作

一、lambda表达式

基本语法:
(parameters) -> expression

(parameters) ->{ statements; }

 

lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

 以下是一些简单的例子,便于我们理解这些特性:

        // 1. 不需要参数,返回值为5() -> 5// 2. 接收一个参数,()可以省略,返回其2倍的值x -> 2 * x// 3. 接受2个参数(数字),并返回他们的差值(x, y) ->x –y// 4. 接收2个int型整数,返回他们的和( int x, int y) ->x + y// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)(String s) ->System.out.print(s)

二、lambda表达式使用

2.1、在for循环中使用

package com.my.controller;import junit.framework.TestCase;
import org.junit.Test;import java.util.ArrayList;
import java.util.List;/*** description:{description}* author:jyy* date:2018-01-09 16:43* modify:{modify}*/
public class AppTest extends TestCase {@Testpublic void test() {List<String> list = new ArrayList<>();list.add("北京");list.add("上海");list.add("广州");list.add("深圳");for (String str : list) {System.out.println(str);}System.out.println("=================");list.forEach(str -> System.out.println(str));}}

执行结果:

北京
上海
广州
深圳
=================
北京
上海
广州
深圳

2.2、替代匿名内部类使用

我们使用JAVA基础知识|内部类中的try catch示例

package com.my.controller;import junit.framework.TestCase;
import org.junit.Test;import java.util.ArrayList;
import java.util.List;/*** description:{description}* author:jyy* date:2018-01-09 16:43* modify:{modify}*/
public class AppTest extends TestCase {@Testpublic void test() {//匿名内部类new ExceptionTemplate().execute(new CatchExceptionable() {@Overridepublic void catchException() {System.out.println("代码");}});//lambda表达式new ExceptionTemplate().execute(() -> System.out.println("代码"));}}

2.3、lambda表达式与Comparator类结合使用

package com.my.controller;import junit.framework.TestCase;
import org.junit.Test;import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;/*** description:{description}* author:jyy* date:2018-01-09 16:43* modify:{modify}*/
public class AppTest extends TestCase {@Testpublic void test() {List<String> list = new ArrayList<>();list.add("BeiJing");list.add("ShangHai");list.add("GuangZhou");list.add("ShenZhen");list.sort(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o1.compareTo(o2);}});list.forEach(str -> System.out.println(str));System.out.println("==============");List<String> list2 = new ArrayList<>();list2.add("BeiJing");list2.add("ShangHai");list2.add("GuangZhou");list2.add("ShenZhen");//list2.sort((String o1,String o2) -> o1.compareTo(o2));Comparator<String> comparator =(String o1,String o2) -> o1.compareTo(o2);list2.sort(comparator);list2.forEach(str -> System.out.println(str));}
}

执行结果:

BeiJing
GuangZhou
ShangHai
ShenZhen
==============
BeiJing
GuangZhou
ShangHai
ShenZhen

 三、流stream

Java 8 中的stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。stream API 借助于同样新出现的 lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势

生成流的两种方式:

  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。

下面我们就来使用stream提供的各种API:

3.1、筛选和切片

方法描述
filter从流中过滤元素
distinct通过流所生成的元素的hashCode()和equals()方法去重
limit截断流,选取前n个元素
skip跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足n个,则返回一个空流

 

package com.my.po;/*** description:{description}* author:jyy* date:2018-02-11 11:06* modify:{modify}*/
public class Employee {private String id;private String name;private double salary;private String sex;public Employee(String id, String name, double salary,String sex) {this.id = id;this.name = name;this.salary = salary;this.sex=sex;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic String toString() {return "Employee{" +"id='" + id + '\'' +", name='" + name + '\'' +", salary=" + salary +", sex='" + sex + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Employee employee = (Employee) o;return id.equals(employee.id);}@Overridepublic int hashCode() {return id.hashCode();}
}
View Code
package com.my.controller;import com.my.po.Employee;
import junit.framework.TestCase;
import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;/*** description:{description}* author:jyy* date:2018-01-09 16:43* modify:{modify}*/
public class AppTest extends TestCase {@Testpublic void test() {Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1004", "谢楠", 11000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);//forEach,查询所有数据list.stream().forEach(e -> System.out.println(e.toString()));//filter,查询集合中所有的女性list.stream().filter(e -> Objects.equals(e.getSex(), "female")).forEach(e -> System.out.println(e.toString()));//查询集合中薪资大于6000的雇员list.stream().filter(e -> e.getSalary() > 7000).forEach(e -> System.out.println(e));//limit,查询前两条数据list.stream().limit(2).forEach(e -> System.out.println(e.toString()));//distinct,去重,利用Employee对象中的hashCode()和equals()方法list.stream().distinct().forEach(e -> System.out.println(e));//skip,跳过前两个list.stream().skip(2).forEach(e -> System.out.println(e));}
}
View Code

3.2、映射

方法描述
 map(Function f) 接受一个函数作为参数,并将函数应用到每一个元素上,返回新的元素
 mapToDouble(ToDoubleFunction f) 返回的新元素为double类型
 mapToInt(ToIntFunction f) 返回的新元素为int类型
 mapToLong(ToLongFunction f) 返回的新元素为long类型
 flatMap(Function f) 操作多层嵌套的流,使其扁平化

 3.2.1、map

        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1004", "谢楠", 11000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);//maplist.stream().map(e -> e.getSalary()).forEach(e -> System.out.println(e));

执行结果:

5000.0
7000.0
10000.0
11000.0
11000.0

可以看出,集合list经过map操作之后,类型已经改变。具体什么类型,由返回值决定

3.2.2、mapToDouble、mapToInt、mapToLong

        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1004", "谢楠", 11000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);list.stream().mapToDouble(e -> e.getSalary()).forEach(e -> System.out.println(e));

执行结果:

5000.0
7000.0
10000.0
11000.0
11000.0

3.2.3、flatMap

        Employee[] employees1 = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1004", "谢楠", 11000, "female")};Employee[] employees2 = {new Employee("1005", "Marry", 5000, "male"),new Employee("1006", "Linda", 7000, "male"),new Employee("1007", "Cris", 10000, "female")};List<Employee[]> list = new ArrayList<>();list.add(employees1);list.add(employees2);list.stream().flatMap(e -> Arrays.stream(e)).forEach(e -> System.out.println(e.toString()));

执行结果:

Employee{id='1001', name='李明', salary=5000.0, sex='male'}
Employee{id='1002', name='王明', salary=7000.0, sex='male'}
Employee{id='1003', name='张丽', salary=10000.0, sex='female'}
Employee{id='1004', name='谢楠', salary=11000.0, sex='female'}
Employee{id='1005', name='Marry', salary=5000.0, sex='male'}
Employee{id='1006', name='Linda', salary=7000.0, sex='male'}
Employee{id='1007', name='Cris', salary=10000.0, sex='female'}

 3.3、排序

方法描述
sorted()产生一个新流,其中按自然顺序排序
sorted(Comparator comp)产生一个新流,其中按比较器顺序排序
        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1005", "Marry", 6000, "male"),new Employee("1006", "Linda", 9000, "male"),new Employee("1007", "Cris", 10000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);list.stream().map(e -> e.getSalary()).sorted().forEach(e -> System.out.println(e.toString()));System.out.println("=======");Comparator<String> comparator = (String o1, String o2) -> o1.compareTo(o2);list.stream().map(e -> e.getId()).sorted(comparator).forEach(e -> System.out.println(e.toString()));

执行结果:

5000.0
6000.0
7000.0
9000.0
10000.0
10000.0
11000.0
=======
1001
1002
1003
1004
1005
1006
1007

3.4、查找与匹配

方法描述
allMatch(Predicate p)检查是否匹配所有元素
anyMatch(Predicate p)检查是否至少匹配一个元素
noneMatch(Predicate p)检查是否没有匹配所有元素
findFirst()返回第一个元素
findAny()返回当前流中的任意元素
count()返回流中元素总数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值
forEach(Consumer c)内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了)
        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1005", "Marry", 6000, "male"),new Employee("1006", "Linda", 9000, "male"),new Employee("1007", "Cris", 10000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);System.out.println("===allMatch===");Boolean b1 = list.stream().allMatch(e -> e.getSalary() > 4000);Boolean b2 = list.stream().allMatch(e -> e.getSalary() > 5000);System.out.println(b1);System.out.println(b2);System.out.println("===anyMatch===");Boolean b3 = list.stream().anyMatch(e -> e.getSalary() > 10000);Boolean b4 = list.stream().anyMatch(e -> e.getSalary() > 11000);System.out.println(b3);System.out.println(b4);System.out.println("===noneMatch===");Boolean b5 = list.stream().noneMatch(e -> e.getSalary() > 10000);Boolean b6 = list.stream().noneMatch(e -> e.getSalary() > 11000);System.out.println(b5);System.out.println(b6);System.out.println("===findFirst===");System.out.println(list.stream().findFirst().toString());System.out.println("===findAny===");System.out.println(list.stream().findAny().toString());System.out.println("===count===");System.out.println(list.stream().count());System.out.println("===max===");System.out.println(list.stream().max((Employee o1, Employee o2) -> {if (o1.getSalary() > o2.getSalary()) return 1;else return -1;}).toString());System.out.println("===min===");System.out.println(list.stream().min((Employee o1, Employee o2) -> {if (o1.getSalary() > o2.getSalary()) return 1;else return -1;}).toString());

执行结果:

===allMatch===
true
false
===anyMatch===
true
false
===noneMatch===
false
true
===findFirst===
Optional[Employee{id='1001', name='李明', salary=5000.0, sex='male'}]
===findAny===
Optional[Employee{id='1001', name='李明', salary=5000.0, sex='male'}]
===count===
7
===max===
Optional[Employee{id='1004', name='谢楠', salary=11000.0, sex='female'}]
===min===
Optional[Employee{id='1001', name='李明', salary=5000.0, sex='male'}]

 3.5、归约

map-reduce模式,在mongoDB、spark、hadoop等都有它的身影,因google使用它进行网络搜索而出名

方法描述
reduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回Optional<T>
        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1005", "Marry", 6000, "male"),new Employee("1006", "Linda", 9000, "male"),new Employee("1007", "Cris", 10000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);String result1 = list.stream().map(e -> e.getName()).reduce("", (x, y) -> x + "," + y);System.out.println(result1.substring(1));Optional<String> result2 = list.stream().map(e -> e.getName()).reduce((x, y) -> x + "," + y);System.out.println(result2.get());

执行结果:

李明,王明,张丽,Marry,Linda,Cris,谢楠
李明,王明,张丽,Marry,Linda,Cris,谢楠

3.6、收集

方法描述
collect(Collector c)将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
        Employee[] employees = {new Employee("1001", "李明", 5000, "male"),new Employee("1002", "王明", 7000, "male"),new Employee("1003", "张丽", 10000, "female"),new Employee("1005", "Marry", 6000, "male"),new Employee("1006", "Linda", 9000, "male"),new Employee("1007", "Cris", 10000, "female"),new Employee("1004", "谢楠", 11000, "female")};List<Employee> list = Arrays.asList(employees);List<String> collect = list.stream().map(e -> e.getName()).collect(Collectors.toList());collect.forEach(System.out::println);System.out.println("-------------------");Set<String> set = list.stream().map(e -> e.getName()).collect(Collectors.toSet());set.forEach(System.out::println);System.out.println("-------------------");HashSet<String> hashSet = list.stream().map(e -> e.getName()).collect(Collectors.toCollection(HashSet::new));hashSet.forEach(System.out::println);System.out.println("-------------------");//分组Map<Double, List<Employee>> group = list.stream().collect(Collectors.groupingBy(e -> e.getSalary()));System.out.println(group);

执行结果:

李明
王明
张丽
Marry
Linda
Cris
谢楠
-------------------
张丽
Cris
李明
王明
Linda
Marry
谢楠
-------------------
张丽
Cris
李明
王明
Linda
Marry
谢楠
{9000.0=[Employee{id='1006', name='Linda', salary=9000.0, sex='male'}], 10000.0=[Employee{id='1003', name='张丽', salary=10000.0, sex='female'}, Employee{id='1007', name='Cris', salary=10000.0, sex='female'}], 5000.0=[Employee{id='1001', name='李明', salary=5000.0, sex='male'}], 11000.0=[Employee{id='1004', name='谢楠', salary=11000.0, sex='female'}], 6000.0=[Employee{id='1005', name='Marry', salary=6000.0, sex='male'}], 7000.0=[Employee{id='1002', name='王明', salary=7000.0, sex='male'}]}

以上内容只是对lambda表达式和stream的简单介绍,在实际使用中要复杂的多

 

转载于:https://www.cnblogs.com/maikucha/p/8435906.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库:存储过程_数据科学过程:摘要

数据库:存储过程Once you begin studying data science, you will hear something called ‘data science process’. This expression refers to a five stage process that usually data scientists perform when working on a project. In this post I will walk through ea…

901

901 转载于:https://www.cnblogs.com/Forever77/p/11542129.html

leetcode 137. 只出现一次的数字 II(位运算)

给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 示例 1&#xff1a; 输入&#xff1a;nums [2,2,3,2] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;nums [0,1,0,…

【p081】ISBN号码

Time Limit: 1 second Memory Limit: 50 MB 【问题描述】 每一本正式出版的图书都有一个ISBN号码与之对应&#xff0c;ISBN码包括9位数字、1位识别码和3位分隔符&#xff0c;其规定格式如“x-xxx-xxxxx-x”&#xff0c;其中符号“-”是分隔符&#xff08;键盘上的减号&#xff…

gitlab bash_如何编写Bash一线式以克隆和管理GitHub和GitLab存储库

gitlab bashFew things are more satisfying to me than one elegant line of Bash that automates hours of tedious work. 没有什么比让Bash自动完成数小时繁琐工作的Bash优雅系列令我满意的了。 As part of some recent explorations into automatically re-creating my la…

寒假学习笔记(4)

2018.2.11 类中的常成员 关键字const&#xff0c;在类定义中声明数据成员使用关键字限定&#xff0c;声明时不能初始化。初始化列表&#xff0c;类中的任何函数都不能对常数据成员赋值&#xff0c;包括构造函数。为构造函数添加初始化列表是对常数据成员进行初始化的唯一途径。…

svm和k-最近邻_使用K最近邻的电影推荐和评级预测

svm和k-最近邻Recommendation systems are becoming increasingly important in today’s hectic world. People are always in the lookout for products/services that are best suited for them. Therefore, the recommendation systems are important as they help them ma…

Oracle:时间字段模糊查询

需要查询某一天的数据&#xff0c;但是库里面存的是下图date类型 将Oracle中时间字段转化成字符串&#xff0c;然后进行字符串模糊查询 select * from CAINIAO_MONITOR_MSG t WHERE to_char(t.CREATE_TIME,yyyy-MM-dd) like 2019-09-12 转载于:https://www.cnblogs.com/gcgc/p/…

cogs2109 [NOIP2015] 运输计划

cogs2109 [NOIP2015] 运输计划 二分答案树上差分。 STO链剖巨佬们我不会&#xff08;太虚伪了吧 首先二分一个答案&#xff0c;下界为0,上界为max{路径长度}。 然后判断一个答案是否可行&#xff0c;这里用到树上差分。 &#xff08;阔以理解为前缀和&#xff1f;&#xff1f;&…

leetcode 690. 员工的重要性(dfs)

给定一个保存员工信息的数据结构&#xff0c;它包含了员工 唯一的 id &#xff0c;重要度 和 直系下属的 id 。 比如&#xff0c;员工 1 是员工 2 的领导&#xff0c;员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] &#x…

组件分页_如何创建分页组件

组件分页The theme for week #17 of the Weekly Coding Challenge is:每周编码挑战第17周的主题是&#xff1a; 分页 (Pagination) A Pagination Component is used on websites where you have more content available than you want to display at one time to the user so …

web-项目管理

总结 目的是 1.可查询 2.方便团队管理 每个成员都可以看到任何东西 项目 需求 计划 bug 按模板来 1.问题描述 2.原因分析 3.解决方法 开发 提交代码 按模板来 1.问题描述 2.原因分析 3.解决方法 打包 更新说明文件.txt 按模板来 一、更新说明 1.问题描述 1&#xff09;计划号 2…

cnn对网络数据预处理_CNN中的数据预处理和网络构建

cnn对网络数据预处理In this article, we will go through the end-to-end pipeline of training convolution neural networks, i.e. organizing the data into directories, preprocessing, data augmentation, model building, etc.在本文中&#xff0c;我们将遍历训练卷积神…

leetcode 554. 砖墙

你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同&#xff08;也就是一个单位高&#xff09;但是宽度不同。每一行砖块的宽度之和应该相等。 你现在要画一条 自顶向下 的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过&#xff0c;就不算穿过这块砖…

django-rest-framework解析请求参数过程详解

https://www.jb51.net/article/165699.htm 转载于:https://www.cnblogs.com/gcgc/p/11544187.html

递归 和 迭代 斐波那契数列

#include "stdio.h"int Fbi(int i) /* 斐波那契的递归函数 */ { if( i < 2 ) return i 0 ? 0 : 1; return Fbi(i - 1) Fbi(i - 2); /* 这里Fbi就是函数自己&#xff0c;等于在调用自己 */ }int main() { int i; int a[40]; printf("迭代显示斐波那契数列…

单元测试 python_Python单元测试简介

单元测试 pythonYou just finished writing a piece of code and you are wondering what to do. Will you submit a pull request and have your teammates review the code? Or will you manually test the code? 您刚刚编写了一段代码&#xff0c;并且想知道该怎么做。 您…

飞行模式的开启和关闭

2019独角兽企业重金招聘Python工程师标准>>> if(Settings.System.getString(getActivity().getContentResolver(),Settings.Global.AIRPLANE_MODE_ON).equals("0")) { Settings.System.putInt(getActivity().getContentResolver(),Settings.Global.AIRPLA…

消解原理推理_什么是推理统计中的Z检验及其工作原理?

消解原理推理I Feel:我觉得&#xff1a; The more you analyze the data the more enlightened, data engineer you will become.您对数据的分析越多&#xff0c;您将变得越发开明。 In data engineering, you will always find an instance where you need to establish whet…

pytest+allure测试框架搭建

https://blog.csdn.net/wust_lh/article/details/86685912 https://www.jianshu.com/p/9673b2aeb0d3 定制化展示数据 https://blog.csdn.net/qw943571775/article/details/99634577 环境说明&#xff1a; jdk 1.8 python 3.5.3 allure-commandline 2.13.0 文档及下载地址&…