java8
Posted aishuijdemiaomiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8相关的知识,希望对你有一定的参考价值。
Lambda表达式
- 又称为函数式编程
- lambda只能适用于一个方法的接口,
- 匿名函数,代替匿名内部类的对象
- ()代表方法的参数列表,-> 转向符,表示参数如何被处理,右面就时被处理的细节
- Runnable runnable2 = () -> {...}; //...表示被覆盖的方法
- 目的,精炼,过长不适用
- 原理,类型推断(新特性)
- 由于类型推断的使用,当参数列表类型确定时类型可省
- return可省略
- 一个语句可省略大括号
- 凡是可推断的都可省略
Runnable runnable = () -> {System.out.println("hello");};
接口类型
- static, 允许有静态方法,也有方法体,静态方法的作用就是通过接口类来调用,适用于接口都的功能性增强,调用简单
- default, 允许有默认方法,也有方法体,作用时增强接口的功能性,并且在不改变原有子类的情况下做到
- 向抽象类靠拢。
- 接口类型
- 消费型接口 : 只进行方法执行,没有返回值。
- 供给型接口
- 函数型接口
- 断定型接口
函数式接口
- 只有一个抽象方法的接口
- 支持泛型
- 对一些特定的方法行为模式的抽象
- Consumer
是消费器,给它传一个对象,没有返回 - public void accept(T t);
- Supplier
是供给器,只需要调用它,则能返回T类型对象,(无参构造器) - T get()
- Function<T, R> 是装环器,需要t类型的对象,经过某种处理之后返回r型的对象
- R apply(T t)
- Predicate
是断定器,需要一个T类型的对象,经过某种判断,返回真或假,有参,返回布尔值 - boolean test(T t)
- Consumer
- 其他接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
BiFunction<T, U, R> | T, U | R | 对类型为 T, U 参数应用操作,返回 R 类型的结果。包含方法为 R apply(T t, U u); |
UnaryOperator |
T | T | 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为 T apply(T t); |
BinaryOperator |
T, T | T | 对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为 T apply(T t1, T t2); |
BiConsumer<T, U> | T, U | void | 对类型为T, U 参数应用操作。包含方法为 void accept(T t, U u) |
BiPredicate<T,U> | T,U | boolean | 包含方法为 boolean test(T t,U u) |
ToIntFunction |
T | int long double | 分别计算int、long、double、值的函数 |
IntFunction |
int long double | R | 参数分别为int、long、double 类型的函数 |
- 方法引用
- 只要接口中的方法模式和已有方法一样,就可以直接使用已有方法作为实现!!!
- 对象::实例方法名
- 类::静态方法名
- 类::实例方法名
- 啊啊啊,java实现了对方法的引用,又不会编程了(上次是反射刷新了我对java的认识)。。。
Consumer<String> c1 = System.out::println;
c1.accept("124");
Stream api
集合数据处理,上面的都是为它服务的。。。
特点
- 对象流,处理批量对象的思路
- 对集合中的批量数据进行sql类似的方式进行处理
- 重点是计算,处理
- 不是集合,而是流
- stream不会改变源对象,会返回持有结果的新对象
- Stream操作时延迟执行的,先积攒后执行,提供效率
- Stream只能消费一次,类似于Thread
- 高级iterator一次,不可往复,数据只能遍历一次,但是可以并行化数据。
- 工作窃取,多线程处理数据可以协调处理
步骤
创建
- 基于集合:集合对象.stream()
- 基于数组:Arrays.stream(arr)
- 基于散数据:Stream.of(T...values);
- 无限流Stream.gemerate(Supplier sup);
中间操作,任务开始执行,相当于Thread里的start方法
- Stream filter(Predicate p)接受lambda,把流中的每个对象经过判定器,为真留下,假的丢弃
- Stream distinct(); 筛选器,去重,使用equal和hashcode去重
- limit(long maxSize); 截断流,限制个数
- skip(long n); 跳过元素,跳过前n个元素
- sorted(); 自然排序
- sorted(Comptaretor c); 定制排序,加比价器
- map(Funtion f); 映射,使用转换器
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
---|---|
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。 |
mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。 |
mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。 |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
终止操作
1. foreach(Consumer consumer);把每个数据经过消费器消费。
匹配与查找
方法 | 描述 |
---|---|
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
查找遍历
方法 | 描述 |
---|---|
count() | 返回流中元素总数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了) |
归约,归纳,把逐渐每个元素拿出来运算
方法 | 描述 |
---|---|
reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 T |
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional |
//基于集合
public void test4() {
List<Student> list = StudentData.getList();
Stream<Student> stream = list.stream();
stream.forEach(System.out::println);
}
//基于无限流
public void test3() {
Stream<Double> stream = Stream.generate(() -> Math.random());
stream.forEach(System.out::println);
}
//基于散数据
public void test2() {
Stream<String> of = Stream.of("123", "agasd", "12a", "asdfa");
of.forEach(System.out::println);
}
//基于数组数组
public void test1() {
List<Student> list = StudentData.getList();
Student[] students = null;
list.toArray(students);
Stream<Student> stream = Arrays.stream(students);
stream.forEach(System.out::println);
}
//举例:
public class Main4 {
@Test
public void test1() {
//Student泛型传递
List<Student> list = StudentData.getList(); //StudentDate的静态方法可拿到javaBean类:Student.
//.筛选器.筛选器.排序.限制器.终止操作。
list.stream().filter(t -> t.getGrade() == 3).filter(t -> t.getScore() < 60).sorted().limit(3).forEach(System.out::println);
}
}
并行
- 并行流,串行流
Optional 类
- 最大渐少空指针异常
- Optional
类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
-常用方法:- Optional.empty() : 创建一个空的 Optional 实例
- Optional.of(T t) : 创建一个 Optional 实例
- Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
- isPresent() : 判断是否包含值
- T get(): 如果调用对象包含值,返回该值,否则抛异常
- orElse(T t): 如果调用对象包含值,返回该值,否则返回t;不确定结果是否为空,或者有可能为null,都可以使用此方法,若为空得到预置的对象
- orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
- map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
- flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
以上是关于java8的主要内容,如果未能解决你的问题,请参考以下文章
Java8 Stream针对List先分组再求和最大值最小值平均值等