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)
  • 其他接口
函数式接口 参数类型 返回类型 用途
BiFunction<T, U, R> T, U R 对类型为 T, U 参数应用操作,返回 R 类型的结果。包含方法为 R apply(T t, U u);
UnaryOperator (Function子接口) T T 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为 T apply(T t);
BinaryOperator (BiFunction 子接口) 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 ToLongFunction ToDoubleFunction T int long double 分别计算int、long、double、值的函数
IntFunction LongFunction DoubleFunction int long double R 参数分别为int、long、double 类型的函数
  • 方法引用
    • 只要接口中的方法模式和已有方法一样,就可以直接使用已有方法作为实现!!!
    • 对象::实例方法名
    • 类::静态方法名
    • 类::实例方法名
    • 啊啊啊,java实现了对方法的引用,又不会编程了(上次是反射刷新了我对java的认识)。。。
Consumer<String> c1 = System.out::println;
c1.accept("124");


Stream api

 集合数据处理,上面的都是为它服务的。。。
特点
  • 对象流,处理批量对象的思路
  • 对集合中的批量数据进行sql类似的方式进行处理
  • 重点是计算,处理
  1. 不是集合,而是流
    1. stream不会改变源对象,会返回持有结果的新对象
    2. Stream操作时延迟执行的,先积攒后执行,提供效率
    3. Stream只能消费一次,类似于Thread
    4. 高级iterator一次,不可往复,数据只能遍历一次,但是可以并行化数据。
      • 工作窃取,多线程处理数据可以协调处理

步骤

创建

  1. 基于集合:集合对象.stream()
  2. 基于数组:Arrays.stream(arr)
  3. 基于散数据:Stream.of(T...values);
  4. 无限流Stream.gemerate(Supplier sup);

中间操作,任务开始执行,相当于Thread里的start方法

  1. Stream filter(Predicate p)接受lambda,把流中的每个对象经过判定器,为真留下,假的丢弃
  2. Stream distinct(); 筛选器,去重,使用equal和hashcode去重
  3. limit(long maxSize); 截断流,限制个数
  4. skip(long n); 跳过元素,跳过前n个元素
  5. sorted(); 自然排序
  6. sorted(Comptaretor c); 定制排序,加比价器
  7. 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先分组再求和最大值最小值平均值等

通过 Java 正则表达式提取 semver 版本字符串的片段

Java 8 新特性总结

Java Lambda

函数式编程

java代码之美(14)---Java8 函数式接口