java基础之lambda表达式

                            java基础之lambda表达式

1 什么是lambda表达式

lambda表达式是一个匿名函数,允许将一个函数作为另外一个函数的参数,将函数作为参数传递(可理解为一段传递的代码)。

2 为什么要用lambda表达式

lambda表达式可以写出更简洁更灵活的代码。先看看下面一段代码

public class TestLambda {//匿名内部类方式@Testpublic void test() {TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {			return Integer.compare(o1, o2);}		});}//lambda方式@Testpublic void test1() {Comparator<Integer> com = (x,y)->Integer.compare(x, y);TreeSet<Integer> set = new TreeSet<>(com);		}List<Person> list = Arrays.asList(new Person("小红", 18, 5000.0), new Person("小明", 21, 6000.0),new Person("小刚", 25, 7000.0));// 传统方式获取年龄大于20的人@Testpublic void test2() {for (Person person : list) {if(person.getAge()>20) {System.out.println(person);}}}// lambda方式获取年龄大于20的人@Testpublic void test3() {list.stream().filter((x)-> x.getAge()>20).forEach(System.out::println);}
}

 

3 lambda语法

java8中引入了操作符“->”,称为箭头操作符或lambda操作符,lambda用于替换匿名函数。

使用lambda表达式的前提:接口(函数式接口)中只能有一个抽象方法。

函数式接口:接口中只有一个抽象方法的接口,通过注解@Functioninterface 限定

lambda操作符将lambda表达式拆成两个部分:

(1)左侧是lambda表达式的参数列表(可以理解为抽象方法的参数)

(2)右侧是lambda表达式中需要执行的功能,即lambda体(可以理解为抽象方法的实现的功能)

3.1 格式一:无参数,无返回值

()->System.out.println("Hello Lambda!");

3.2 格式二:有一个参数,无返回值(如果只有一个参数可以省略(),如果只有一条语法可以省略{})

(x)->System.out.println(x);

3.3 格式三:如果只有一个参数,小括号可以省略不写

x -> System.out.println(x);

3.4 格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句

Comparator<Integer> com = (x, y) -> {

          System.out.println("函数式接口");

           return Integer.compare(x, y);

};

3.5 格式五:如果 Lambda 体中只有一条语句, return 和 大括号都可以省略不写

Comparator<Integer> com = (x, y) -> Integer.compare(x, y);

3.6 格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”

(Integer x, Integer y) -> Integer.compare(x, y);

 

4 内置的四个核心函数式接口

4.1 消费型接口Consumer<T>

抽象方法:void accept(T t);

    //消费型接口@Testpublic void test1() {//	Consumer<Double> con = (x)-> System.out.print(x);//	consumer(100, con);consumer(100,(x)-> System.out.print(x));}public void consumer(double money,Consumer<Double> con){con.accept(money);}

4.2 供给型接口Supplier<T>

抽象方法:T get();

	//供给型接口@Testpublic void test2() {List<Integer> randomNum = getRandomNum(10,()->new Random().nextInt(100));System.out.println(randomNum);}/*** @Description 生成指定个数的随机数* @param count* @param su* @return int*/public List<Integer> getRandomNum(int count,Supplier<Integer> su) {List<Integer> list = new ArrayList<>();for(int i = 0;i<count;i++) {list.add(su.get());}return list;}

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

抽象方法:R apply(T t);

	//函数式型接口@Testpublic void test3() {List<String> list = toUpperList(new ArrayList<String>(Arrays.asList("abc","df","aa","cc")),(x)-> x.toUpperCase());System.out.println(list);}/*** @Description 将集合里面的字符串转大写* @param list* @param fun* @return List<String>*/public List<String> toUpperList(List<String> list,Function<String,String> fun){for(int i = 0;i < list.size();i++) {String apply = fun.apply(list.get(i));list.set(i, apply);}	return list;	}

4.4 断言型接口Predicate<T>

抽象方法:boolean test(T t);

//断言型接口@Testpublic void test4() {List<String> list = Remove(new ArrayList<String>(Arrays.asList("abc","df","aa","cc")),(s) -> s.length() < 2);System.out.println(list);}/*** @Description 删除集合中长度小于2的元素* @param list* @param pre* @return List<String>*/public List<String> Remove(List<String> list,Predicate<String> pre) {Iterator<String> it = list.iterator();while(it.hasNext()) {String str = it.next();if(pre.test(str)) {list.remove(str);}}return list;}

5 方法引用

5.1 方法引用

将Lambda体中的功能,已有方法方法提供了实现,可以使用方法引用(方法引用可以理解为Lambda的另一种表现形式)

方法引用分类:

(1)对象的引用::实例方法名

    //对象的引用::实例方法名@Testpublic void test1() {Date date = new Date();//传统lambda表达式Supplier<Long> su = ()-> date.getTime();System.out.println(su.get());//对象引用Supplier<Long> su1 = date::getTime;System.out.println(su1.get());}

(2)类名::静态方法名

    //类名::静态方法名@Testpublic void test2() {Comparator<Integer> com = (x,y)-> Integer.compare(x, y);System.out.println(com.compare(4, 5));Comparator<Integer> com1 = Integer::compare;System.out.println(com1.compare(4, 5));}

(3)类名::实例方法名

    //类名::实例方法名@Testpublic void test3() {Function<Person,String> fun = (x)-> x.show();System.out.println(fun.apply(new Person()));Function<Person,String> fun1 = Person::show;System.out.println(fun.apply(new Person()));}class Person{public String show() {return "aaa";}}

注意:方法引用所引用的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致。若Lambda的参数列表的第一个参数,是实例方法的调用,第二个参数(或无参)是实例方法的参数是,格式:ClassName::MethodName

5.2 构造器引用

构造器中的参数列表需要与函数式中参数列表保持一致

类名::new 

    //类名 :: new@Testpublic void test4() {Supplier<Person> sup = () -> new Person();System.out.println(sup.get());Supplier<Person> sup2 = Person::new;System.out.println(sup2.get());}

 

6 Stream

6.1 什么是Stream

Stream流是数据管道,用于操作数据源(集合,数组)所产生的元素序列。

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,需要对元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。Stream是单向的数据只能遍历一次。迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。

注意:①stream自己不会存储元素;②stream不会改变对象,他会返回一个新的stream;③stream的操作是延迟的。

6.2 Stream的操作

操作步骤:①创建Stream;②中间操作;③终止操作

(1)创建流

    @Testpublic void test1() {//1.Collection获取流,获取到的是顺序流List<String> list = new ArrayList<>();Stream<String> stream = list.stream();//2.通过Arrays中的stream获取一个数组流String[] arr = new String[5];Stream<String> stream2 = Arrays.stream(arr);//3.通过Stream类中的静态方法ofStream<Integer> of = Stream.of(11,22,33,44,55);//4.创建无限流Stream<Integer> limit = Stream.iterate(0, (x)-> x + 1).limit(20);limit.forEach(System.out::println);//5.用Stream的generate生成Stream<Double> limit2 = Stream.generate(Math::random).limit(20);limit2.forEach(System.out::println);}

(2)中间操作:

常用中间操作方法如下:

方法描述
Stream<T> filter(Predicate<? super T> predicate)接收Lambda,从流中排除某些元素
Stream<T> limit(long maxSize)截断流,使元素不超过给定数量
Stream<T> skip(long n) 

 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个流,与limit(n)互补

Stream<T> distinct()帅选通过流所生成元素的 hashCode() 和 equals() 去除重复元素
<R> Stream<R> map(Function<? super T,? extends R> mapper)

接收一个lambda,将元素转成成其他形式或提取信息,接收一个函数作为参数,该函数会被 应用到个元素上,并将其映射成一个新元素

(3)终止操作

常用终止操作如下

方法描述
boolean allMatch(Predicate<? super T> predicate)  

检查是否匹配所有元素

boolean anyMatch(Predicate<? super T> predicate)  

检查是否至少匹配一个元素

boolean noneMatch(Predicate<? super T> predicate)  

检查是否没有匹配的元素

Optional<T> findFirst()  

返回第一个元素

Optional<T> findAny()  

返回当前流中的任意元素

long count()

返回流中元素的总个数

Optional<T> max(Comparator<? super T> comparator)  

返回流中最大值

Optional<T> min(Comparator<? super T> comparator) 

返回流中最小值

案例:

@Testpublic void test2() {List<String> list = Arrays.asList("a","d","e","b","c");//自然排序list.stream().sorted().forEach(System.out::println);//定制排序List<Person> p = new ArrayList<>();p.add(new Person("aa",18,100.0));p.add(new Person("cc",16,150.0));p.add(new Person("bb",20,180.0));p.stream().sorted((e1,e2)->{if(e1.getAge()==e2.getAge()) {return e1.getName().compareTo(e2.getName());}else {return e1.getAge()-e2.getAge();}}).forEach(System.out::println);}class Person {private String name;private int age;private double score;public Person() {}public Person(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}@Overridepublic String toString() {return "Person1 [name=" + name + ", age=" + age + ", score=" + score + "]";}}

 

 

 

 

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

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

相关文章

6.数据查询(条件

查询所有字段select * from 表名; 例&#xff1a;select * from students; 查询指定字段 在select后面的列名部分&#xff0c;可以使用as为列起别名&#xff0c;这个别名出现在结果集中 select 列1,列2,... from 表名; -- 表名.字段名 select students.id,students.name,su…

开源代码分析技巧之——打印调用逻辑

开源代码分析技巧之——打印调用逻辑 在研究开源代码时&#xff0c;大家或许都有这样的感慨&#xff1a; &#xff08;1&#xff09;代码太庞大&#xff0c;少则几万行代码&#xff0c;多则几百万行代码&#xff0c;不知道如何入手&#xff1b; &#xff08;2&#xff09;相关的…

LeetCode 731. 我的日程安排表 II(set二分查找 / 差分思想)

文章目录1. 题目2. 解题2.1 set 二分查找2.2 差分思想1. 题目 实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内不会导致三重预订时&#xff0c;则可以存储这个新的日程安排。 MyCalendar 有一个 book(int start, int end)方法。 它意味着在 start 到 end 时间…

7.排序、聚合函数、分组查询

排序 语法&#xff1a; select * from 表名 order by 列1 asc|desc,列2 asc|desc,... asc从小到大排列&#xff0c;即升序&#xff0c;也可不写&#xff1b; desc从大到小排序&#xff0c;即降序 例1&#xff1a;查询未删除男生信息&#xff0c;按学号降序 select * from…

JSON数据格式以及与后台交互数据转换实例

/*作者&#xff1a;烟大阳仔时间&#xff1a;20131013介绍:主要了解一下json的格式&#xff0c;看看数据是怎么存储的 */ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> &…

05.序列模型 W1.循环序列模型

文章目录1. 为什么选择序列模型2. 数学符号3. 循环Recurrent 神经网络模型4. 通过时间的反向传播5. 不同类型的循环神经网络6. 语言模型和序列生成7. 对新序列采样8. 循环神经网络的梯度消失9. Gated Recurrent Unit&#xff08;GRU单元&#xff09;10. LSTM&#xff08;long s…

8.分页、连接、自关联查询

获取部分行 语法 select * from 表名 limit start,count 从start开始&#xff0c;获取count条数据 start索引从0开始 例1&#xff1a;查询前3行男生信息 select * from students where gender1 limit 0,3; 分页 已知&#xff1a;每页显示m条数据&#xff0c;当前显示第n…

C语言宏定义取得两数的最大值和最小值

/*本程序时为了验证用宏来做 * 两个数的大小比较的写法*/#include<stdio.h>#define MAX(x,y) ((x)<(y)?(y):(x))#define MIN(X,Y) ({\ typeof (X) x_ (X);\ typeof (Y) y_ (Y);\ (x_ < y_) ? x_ : y_; })/*({...})的作用是将内部的几条语句中最后一条的值返回&…

9.数据库中的子查询

子查询 在一个 select 语句中,嵌入了另外一个 select 语句,那么被嵌入的 select 语句称之为子查询语句 主查询 主要查询的对象,第一条 select 语句 主查询和子查询的关系 子查询是嵌入到主查询中 子查询是辅助主查询的,要么充当条件,要么充当数据源 子查询是可以独立存在的语句…

LeetCode 802. 找到最终的安全状态(逆向图+拓扑排序)

文章目录1. 题目2. 解题1. 题目 在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。 现在, 如果我们最后能走到终点&#xff0c;那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K…

oracle 重建 sys密码文件

需要重建密码文件,具体步骤如下: 1.首先,确定你的密码文件的路径和名称: 在windows下 密码文件路径oracle_home\database 密码文件名称pwdsid.ora 在unix下 密码文件路径oracle_home/dbs 密码文件名称pwdsid Sid为实例名称,查看实例名称 Select instance_name from v$in…

10.数据库中的内置函数

字符串函数 查看字符的ascii码值ascii(str)&#xff0c;str是空串时返回0 查看ascii码值对应的字符char(数字)&#xff1a;select char(97); 拼接字符串concat(str1,str2...)&#xff1a;selectconcat(12,34,ab); 包含字符个数length(str)&#xff1a;selectlength(abc); 截…

Java基础10(反射)

Java基础10&#xff08;反射&#xff09; 1 什么是反射 官方解释&#xff1a;反射&#xff08;reflection&#xff09;技术通常被用来检测和改变应用程序在 Java 虚拟机中的行为表现。它是一个相对而言比较高级的技术&#xff0c;反射是一种强有力的技术特性&#xff0c;因此…

05.序列模型 W1.循环序列模型(作业:手写RNN+恐龙名字生成)

文章目录作业1&#xff1a;建立你的循环神经网络1. RNN 前向传播1.1 RNN 单元1.2 RNN 前向传播2. LSTM 网络2.1 LSTM 单元2.2 LSTM 前向传播3. RNN 反向传播3.1 基础 RNN 反向传播3.2 LSTM 反向传播3.3 LSTM RNN网络反向传播作业2&#xff1a;字符级语言模型&#xff1a;恐龙岛…

给年轻工程师的十大忠告

给年轻工程师的十大忠告 转自http://blog.163.com/tgyeboy02126/blog/static/167507500201191102114940/诸位&#xff0c;咱当电子工程师也是十余年了&#xff0c;不算有出息&#xff0c;环顾四周&#xff0c;也没有看见几个有出息的&#xff01;回顾工程师生涯&#xff0c;感…

11.MYSQL高级(一)

1.账户管理 在生产环境下操作数据库时&#xff0c;绝对不可以使用root账户连接&#xff0c;而是创建特定的账户&#xff0c;授予这个账户特定的操作权限&#xff0c;然后连接进行操作&#xff0c;主要的操作就是数据的crud MySQL账户体系&#xff1a;根据账户所具有的权限的不…

SQL2008中Merge的用法

SQL2008中Merge的用法 在SQL2008中&#xff0c;新增了一个关键字&#xff1a;Merge&#xff0c;这个和Oracle的Merge的用法差不多&#xff0c;只是新增了一个delete方法而已。下面就是具体的使用说明&#xff1a; 首先是对merge的使用说明&#xff1a; merge [into][目标表]usi…

LeetCode 1146. 快照数组(哈希map + 有序map)

文章目录1. 题目2. 解题1. 题目 实现支持下列接口的「快照数组」- SnapshotArray&#xff1a; SnapshotArray(int length) - 初始化一个与指定长度相等的 类数组 的数据结构。初始时&#xff0c;每个元素都等于 0。void set(index, val) - 会将指定索引 index 处的元素设置为…

12.MYSQL高级(二)

1.视图&#xff08;重点 视图本质就是对查询的封装&#xff0c;定义视图&#xff0c;建议以v_开头 create view 视图名称 as select语句; 例&#xff1a;创建视图&#xff0c;查询学生对应的成绩信息 create view v_stu_sco as select students.*,scores.score from scores in…

1.NoSQL与MongoDB简介

NoSQL&#xff1a;非关系型数据库 使用范围&#xff1a;论坛、博客、sns、微博 NoSQL优势&#xff1a; 1.易扩展 2.数据量大&#xff0c;高性能 3.灵活的数据模型 4.高可用 MongoDB特点 模式自由 :可以把不同结构的文档存储在同一个数据库里 面向集合的存储&#xff1a;…