函数式接口
一、函数式接口的概述
1.概念
有且仅有一个"抽象方法"的接口
//jdk8以后是可以有非抽象方法的(比如默认方法)
2.如何检测一个接口是不是函数式接口?
@FunctionalInterface
//注解的功能:检测接口是否为函数式接口
3.注意事项
我们在定义函数式接口的时候,就算我们不写@FunctionalInterface注解,只要保证满足有且仅有一个抽象方法的条件,也照样是函数式接口。但是,建议我们加上
二、函数式接口作为方法的参数
如果一个方法的参数是函数式接口,那么我们可以是使用lambda表达式来作为参数传递 //lambda表达式是函数式接口的实现对象
三、函数式接口作为方法的返回值
如果一个方法的返回值是函数式接口,那么我们可以是使用lambda表达式来作为返回值传递 //lambda表达式是函数式接口的实现对象
四、常用的函数式接口之Supplier<T>
1.它是一个生产型接口
2.抽象方法
T get() 按照某种实现逻辑(由Lambda表达式实现)返回一个数据
3.返回值中的泛型是什么意思?
表示你要生产的数据的类型
4.使用场景
任何需要有返回值,但是没有参数的情况
五、常用的函数式接口之Consumer<T>
1.它是一个消费型接口
2.方法
void accept(T t) 对给定的参数执行此操作
default Consumer andThen(Consumer after)返回一个组合的Consumer,依次执行此操作,然后执行after操作
3.参数列表中的泛型是什么意思?
你需要消费的那个数据的类型
4.三个及其以上的Consumer怎么使用?
直接使用链式编程
consumer1.andThen(consumer2).andThen(consumer3).......
5.使用场景
任何有参数但是没有返回值
六、常用的函数式接口之Predicate<T>
1.它是一个判断型接口
2.方法
boolean test(T t) 对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
default Predicate negate() 返回一个逻辑的否定,对应逻辑非
default Predicate and(Predicate other) 返回一个组合判断,对应短路与
default Predicate or(Predicate other) 返回一个组合判断,对应短路或
3.参数列表中的泛型是什么意思?
你需要判断的那个数据的类型
4.使用场景
你需要判断一个数据的时候
七、常用的函数式接口之Function<T R>
1.它是一个类型转换接口
2.方法
R apply(T t) 将此函数应用于给定的参数
default Function andThen(Function after)返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
3.请问T和R两个泛型代表的是什么意思?
T:指的是你需要转换的那个数据的类型
R:指的是你需要转成的那个数据的类型
4.使用场景
当你需要进行数据类型转换的时候
//总结:只要知道下面这些就行
1.生产型接口Supplier<T>
T get();
2.消费型接口Consumer<T>
void accept(T t);
3.判断型接口Predicate<T>
boolean test(T t);
4.转换型接口Function<T R>
R apply(T);
Stream流 //掌握 ☆☆☆☆☆
一、对于jdk的要求
jdk必须大于等于8
二、体验Stream流
1.Stream流和IO流是什么关系?
两者之间没有任何关系(雷锋和雷峰塔的关系)
//这里的流是流水线的意思
2.经过Stream流操作后的数据会不会被保存?操作后对原来的集合有没有影响?
只会被保存在流中,对原来的集合没有影响
//每一个流对象只能使用一次
3.Stream流可以操作哪些数据?
集合、数组、可变参数
三、Stream流的生成操作 //所谓的生成操作就是创建Stream流对象
1.集合
(1)单列集合(Collection)
default Stream<E> stream() 返回一个序列 Stream与此集合作为其来源。
举例:
Stream<String> stream = arr.stream();
(2)双列集合(Map)
//双列集合没有直接生成流的方式,只能将双列集合转成单列集合再使用
*map.keySet().stream();
*map.values().stream();
*map.entrySet().stream();
2.数组
//使用Arrays工具类的stream方法
static IntStream stream(int[] array) 返回具有指定数组的序列IntStream作为其来源。
//代码举例:
public class Demo2 {
public static void main(String[] args) {
int[] ints = {12,45,96,53};
String[] strs ={"王小二","王小三","王小四","王小五","王小六"};
Integer[] integers = {15,85,47,92,54};
Arrays.stream(ints).forEach(System.out::println);
System.out.println();
Arrays.stream(strs).forEach(System.out::println);
System.out.println();
Arrays.stream(integers).forEach(System.out::println);
System.out.println();
}
}
3.可变参数
static <T> Stream<T> of(T... values) 返回其元素是指定值的顺序排序流。
代码举例:
Stream.of(12,45,96,37,58).forEach(System.out::println);
Stream.of("王小二","王小三","王小四","王小五","王小六").forEach(System.out::println);
四、中间操作 //所谓的中间操作指的就是 链式调用
1.Stream filter(Predicate predicate) 用于对流中的数据进行过滤
//返回值:Stream类型,说明支持链式调用 参数:Predicate判断型接口
举例:list.stream().filter((String s)->{return s.leng()==3}).forEach(System.out::println);
2.Stream limit(long maxSize) 返回此流中的元素组成的流,截取前指定参数个数的数据 //在数据库中也有这个方法 limit(0,5)
//返回值:Stream类型,说明支持链式调用 参数:long类型的maxSize,maxSize不是索引,指的是从0索引开始取maxSize个数据
举例:list.stream().limit(5).forEach(System.out::println);
3.Stream skip(long n) 跳过指定参数个数的数据,返回由该流的剩余元素组成的流
//返回值:Stream类型,说明支持链式调用 参数:long类型的n,n不是索引,指的是从0开始,跳过n个数据,取后面的数据
举例:list.stream().skip(5).forEach(System.out::println);
4.static Stream concat(Stream a, Stream b) 合并a和b两个流为一个流
//static :静态方法,使用类名调用 返回值:Stream类型 参数:两个Stream对象,就是我们需要合并的那两个
举例:Stream.concat(stream1,stream2).forEach(System.out::println);
5.Stream distinct() 返回由该流的不同元素(根据Object.equals(Object) )组成的流 //去重
//返回值:Stream类型 说明支持链式调用
举例:list.stream().distinct().forEach(System.out::println);
6. 排序方法
*Stream sorted() 返回由此流的元素组成的流,根据自然顺序排序 //自然排序
//返回值:Stream类型 说明支持链式调用 参数为空说明使用的是自然排序
举例:list.stream().sorted().forEach(System.out::println);
*Stream sorted(Comparator comparator)返回由该流的元素组成的流,根据提供的Comparator进行排序 //比较器排序
//返回值:Stream类型 说明支持链式调用 参数:Comparator:是一个比较规则的接口,需要我们重写里面的compare(T o1, T o2)方法
举例:
list.stream().sorted((Student s1,Student s2)->{return s1.getAge()-s2.getAge()}).forEach(System.out::println);
7.转换方法
*Stream map(Function mapper) 返回由给定函数应用于此流的元素的结果组成的流 //用来转换类型的
//返回值:Stream类型 说明支持链式调用 参数:Function类型转换接口
举例:list.stream().map((String s)->{return Integer.parseInt(s)}).forEach(System.out::println); //将String----->int
*IntStream mapToInt(ToIntFunction mapper)返回一个IntStream其中包含将给定函数应用于此流的元素的结果 //将给的泛型数据转成int类型
//IntStream : 这是int原始专业Stream
参数列表 :ToIntFunction
抽象方法:
int applyAsInt(T value) 将此函数应用于给定的参数。
举例: int sum = list.stream().mapToInt((Student s1)->{return s1.getAge()}).sum();
五、终结操作 //返回值不是Stream
1.void forEach(Consumer action) 对此流的每个元素执行操作
举例:list.stream().forEach((Styring s)->{System.out.println(s)});
2.long count() 返回此流中的元素数
long l = list.stream().count();
六、收集操作 //指的是将Stream流转成集合
1.收集的方法
R collect(Collector collector) 把结果收集到集合中
(1)返回值: R指的是集合
(2)参数 Collector接口
//这个接口不需要我们自己去实现,使用Collectors工具类帮我们去生成
怎么使用Collectors工具类帮我们自动生成Collector对象?
public static Collector toList() 把元素收集到List集合中
举例:List liust = list.stream().collect(Collectors.toList());
public static Collector toSet() 把元素收集到Set集合中
举例:Set set = list.stream().collect(Collectors.toSet());
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中
//"林青霞,30" 字符串 --------------------> ("林青霞",30) Map集合格式
Map map = Arrays.stream().collect(Collectors.toMap((String s)->{return s.split(",")[0]},(String s)->{return Integer.parseInt(s.split(",")[1]})));