函数式编程
函数式编程思想概述
函数式编程思想:重视的是结果,怎么做事情,不重视完成的过程,找谁来做
Lambda表达式
基本格式
(参数类型 参数名) -> {
方法体;
return 返回值;
}
(参数列表):重写抽象方法的参数
->:传递(固定写法):可以把参数传递到方法体中使用
{}:重写抽象方法的方法体及返回语句
Lambda表达式的使用前提:
1.必须有接口
2.接口中有且只能仅有一个抽象方法(函数式接口)
注意:
Lambda表达式是可推导可省略
Lambda表达式的目的就是重写接口中唯一的抽象方法
接口中的抽象方法只有一个,可以推导出重写的就是接口唯一的这个抽象方法,所以代码才能使用lambda简化
Lambda表达式的简化
Lambda表达式的基本格式:
(参数类型 参数名) -> {
方法体;
return 返回值;
}
简化原则:
1.(参数列表):参数列表的数据类型是可以推导出来的,可以省略
(int a)-->(a)
(int a,String s)-->(a,s)
2.(参数列表):参数列表中只有一个参数,()小括号也可以省略,但是参数列表没有参数,()小括号不能省略
(int a)-->(a)-->a
()->不能省略-->()
3.{重写抽象方法的方法体}:重写的方法体,如果只有一行代码(java中行的以分号分隔开的),无论是否有返回值
{ }和一行代码的结束的分号(;)和return关键字可以一起省略不写
注意:这三部分({ } ; return)或者这两部分({ } ;)必须一起省略
函数式接口
定义及使用
函数式接口:接口中有且仅有一个抽象方法的接口
注意:
1.接口中没有抽象方法不行
2.接口中除了唯一的抽象方法,还可以包含其他的方法(默认,静态,私有)
注解: @FunctionalInterface 用来检测接口是否为一个函数式接口
函数式接口的使用:和使用普通的接口是一样的用法
在工作中,一般都使用函数式接口作为方法的参数类型或者返回值类型使用
调用方法传递的参数和方法返回的值,就可以使用Lambda表达式来简化了
Lambda表达式可以看成就是接口实现类对象的一种,其本质就是创建函数式接口的匿名实现类.
函数式接口:Consumer
java.util.function.Consumer:函数式接口
接口中唯一的抽象方法:
void accept(T t) :消费一个指定泛型类型的数据
Consumer接口的泛型使用什么类型,就可以使用accept方法消费(使用)一个什么类型的数据
至于我们怎么使用这个数据,看心情(想怎么使用就怎么使用,可以计算,可以输出…)
函数式接口:Predicate
java.util.function.Predicate:函数式接口
接口中唯一的抽象方法:
boolean test(T t) 用于对接口指定泛型类型的数据进行判断
Predicate接口的泛型使用什么类型,就可以使用test方法判断数据是否满足要求
满足要求:返回true
不满足安全:返回false
函数式接口:Function
java.util.function.Function<T,R>:函数式接口
接口中唯一的抽象方法:
R apply(T t) 根据参数类型T获取类型R类型的返回值,用于类型转换 T转换R
例如:
Function<String,Integer>:根据传递String类型的数据,获取Integer类型的结果
"123"==>123 = Integer.parseInt("123")
Function<String,Person>:根据传递String类型的数据,获取Person类型的结果
"小明"==>Person p = new Person("小明")
函数式接口:Supplier
java.util.function.Supplier:函数式接口
接口中唯一的抽象方法:
T get() 用来获取接口指定泛型类型的数据
Supplier接口使用什么泛型,就可以使用get方法获取一个什么类型的数据
Stream流
概述
我们可以把集合/数组,转换为Stream流,使用Stream流中的方法,对集合/数组进行操作.
流式思想:Stream流只能使用一次,使用完毕,要么终结,要么产生一个新的流对象.之前的流对象就被销毁了,不能再使用.
获取Stream流
1.使用Collection接口中,(jdk1.8之后)定义了一个方法stream,可以把集合转换为Stream流
default Stream<E> stream() 此转换方法只能是Collection接口下的集合使用
2.使用Stream接口中方法of,可以把可变参数(数组)转换为Stream流
java.util.stream.Stream<T>:接口(jdk1.8之后)中
static <T> Stream<T> of(T... values) :方法的参数是一个可变参数,也可以传递数组
Stream的常用方法
流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:
终结方法:返回值类型不再是Stream接口自身类型的方法,因此不再支持类似StringBuilder那样的链式调用。本小节中,终结方法包括count和forEach方法。
非终结方法:返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为非终结方法。)
在上述介绍的各种方法中,凡是返回值仍然为Stream接口的为函数拼接方法,它们支持链式调用;而返回值不再为Stream接口的为终结方法,不再支持链式调用。如下表所示:
方法名 | 方法作用 | 方法种类 | 是否支持链式调用 |
---|---|---|---|
count | 统计个数 | 终结 | 否 |
forEach | 逐一处理 | 终结 | 否 |
filter | 过滤 | 函数拼接 | 是 |
limit | 取用前几个 | 函数拼接 | 是 |
skip | 跳过前几个 | 函数拼接 | 是 |
map | 映射 | 函数拼接 | 是 |
concat | 组合 | 函数拼接 | 是 |
forEach方法:用于遍历
Stream流中的常用方法_forEach:用于遍历Stream流中的元素
void forEach(Consumer<? super T> action) 对此流的每个元素执行操作。
参数:Consumer<? super T> action:是一个消费型的接口,参数可以传递Lambda表达式
唯一的抽象方法:void accept(T t) :消费一个指定泛型类型的数据
注意:forEach方法是一个终结方法,没有返回值;也不能使用链式编程调用Stream流中的其他方法了
count方法:统计个数
Stream流中的常用方法_count方法:统计个数
long count() 返回此流中的元素数。
注意:count方法是一个终结方法,返回值类型是long类型;也不能使用链式编程调用Stream流中的其他方法了
filter方法:过滤
Stream流中的常用方法_filter方法:用于过滤Stream流中的元素
Stream<T> filter(Predicate<? super T> predicate)
参数:Predicate<? super T> predicate:函数式接口,参数传递lambda表达式
唯一的抽象方法:boolean test(T t) 用于对接口指定泛型类型的数据进行判断
注意:
filter方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
limit方法:获取前n个元素
Stream流中的常用方法_limit方法:获取前n个元素
Stream<T> limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。
例如:limit(4);获取流中的前4个元素,把4个元素存储到一个新的Steam流中
注意:
1.传递数字大于流的长度,返回流中所有的元素
2.limit方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
skip:跳过前n个元素
Stream流中的常用方法_skip方法:跳过前n个元素
Stream<T> skip(long n)
注意:
1.skip跳过的元素数量大于流中的个数,返回一个没有元素的空流
2.skip方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
map方法:映射,类型转换
Stream流中的常用方法_map方法:映射,类型转换
<R> Stream<R> map(Function<T,R> mapper)
参数:Function<T,R> mapper:函数式接口,可以传递Lambda表达式
唯一的抽象方法:R apply(T t) 根据参数类型T获取类型R类型的返回值,用于类型转换 T转换R
注意:
map方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
concat方法:组合
Stream流中的常用方法_concat方法:组合,把两个Stream流,组合为一个新的Stream流
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
注意:
concat方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
收集Stream结果
把Stream流转换为集合
把Stream流转换为集合:收集到集合中
使用Stream流中的方法:
R collect(Collector<?> collector) 把Stream流转换为集合
参数:Collector是一个接口,需要传递接口的实现类对象
java.util.stream.Collectors:是一个工具类,里边提供的静态的方法,可以获取Collector接口的实现类对象
static <T> Collector<T,?,List<T>> toList() 返回一个 Collector ,将输入元素累加到一个新的 List 。
static <T> Collector<T,?,Set<T>> toSet() 返回一个 Collector ,将输入元素累加到一个新的 Set 。
代码示例:
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
把Stream流转换为数组
把Stream流转换为数组:收集到数组中
Stream流中的方法:
Object[] toArray() 返回一个包含此流的元素的数组。