Java8新特性

本文详细介绍了Java8的重要特性,包括接口的默认方法及其与抽象类的区别,lambda表达式的概念、使用场景及作用域,函数式接口的定义与四大核心接口,方法引用的四种形式,Optional类的使用以及如何避免空指针异常,最后深入探讨了Stream API的引入原因、概念及操作,包括创建、中间操作和终止操作。通过这些特性,Java8的代码变得更加简洁和高效。
摘要由CSDN通过智能技术生成

一、接口的默认方法

1.1 为什么引入此方法

接口功能扩展
接口可以有实现方法,且无需实现类实现其方法。

  1. 解决接口的修改与现有的实现不兼容的问题;
  2. 接口支持申明带实现的方法;

1.2 什么是默认方法

  1. 接口中使用default关键字修饰的方法:一个接口中可以存在多个默认方法
  2. 静态默认方法:接口中可以申明静态方法

1.3 和抽象类的区别

  1. 继承关系:一个类只能继承一个抽象类,但可以实现多个接口
  2. 变量:抽象类有实例变量,接口只能有类变量

1.4 多个默认方法解决方案

  1. 创建自己的默认方法,来覆盖重写接口的默认方法
  2. 使用super来现实调用指定的默认方法

二、lambda表达式

2.1 什么是lambda表达式

lambda表达式通常是一个函数,Java中的lambda表达式将函数的概念引入到语言中。
lambda理解为一种具有更紧凑语法的匿名方法,允许省略修饰符、返回类型、特种情况允许省略参数类型。

2.2 为什么使用lambda表达式

  1. 代码简洁、使用灵活、更具阅读性
  2. lambda表达式是一种紧凑的、传递行为的方式

2.3 语法与使用

  • 语法
    1. (parameters)->expression
    2. (parameters)->{statements;}
  • 使用
    1. 使用lambda表达式排序集合
      Collections.sort(list,(String a,String b)->b.compareTo(a));
      list.sort((a,b)->b.compareTo(a));
    2. 与stream结合使用
      list.stream().filter(§->(p.getSalary()>1400)).collect(Collectors.toList());

2.4 lambda表达式作用域

  1. 访问局部变量
    • 使用final修饰的局部变量
    • 隐性的final语法,即在lambda表达式之后不被修改的局部变量
  2. 访问对象字段与静态变量
    • 可读可写
  3. 不可访问接口的默认方法
  4. 使用this会引用创建该lambda表达式的方法的this参数

三、函数式接口

3.1 什么是函数式接口

  • 定义:有且仅有一个抽象方法的接口

3.2 为什么有函数式接口

  1. lambda表达式是对象,必须依附于一类特别的对象类型,即函数式接口。
  2. 函数式接口用于表示lambda表达式的类型。

3.3 内置四大核心函数式接口

函数式接口参数类型返回类型用途
Consumer消费型接口Tvoid对类型为T的对象应用操作,包含方法void accept(T t)
Predicate断定型接口Tboolean确定类型为T的对象是否满足某约束,并返回boolean值。包含方法boolean test(T t)
Supplier供给型接口T返回类型为T的对象,包含方法T get()
Function<T,R>函数型接口TR对类型为T的对象应用操作,并返回R类型的对象结果。包含方法R apply(T t)

四、方法的引用

4.1 为什么有方法引用

就是一个另类的lambda表达式,仅调用一个已存在的方法,不做其他处理。操作符是“::”。

4.2 方法引用的四种形式

类型语法
静态方法引用类名::静态方法
非静态方法引用对象::非静态方法
构造方法引用类名::new
本类非静态方法引用this::非静态方法
//静态方法引用(类名::方法名)
Function<String,Integer> fun1=s->Integer.parseInt(s);
Function<String,Integer> fun2=Integer::parseInt;
//非静态方法引用
Function<String,Boolean> fun1=s->list.add(s);
Function<String,Boolean> fun2=s->list::add;
//构造方法引用(类名::new)
Function<String,Method> fun1=s->new Method(s);
Function<String,Method> fun1=Method::new;//类引用单参构造方法
Function<String,Integer,Method> fun2=(s,i)->new Method(s,i);
Function<String,Integer,Method> fun2=Method::new;//类引用双参构造方法
//本类非静态方法引用(this::方法名)
Function<String,Integer> fun1=s->love(s);
Function<String,Integer> fun1=this::love;
Function<String,Integer> fun2=s->super.love(s);
Function<String,Integer> fun2=super::love;//扩展:子类可以使用suoer调用父类方法

五、Optional类

5.1 为什么有Optional类

  • 避免出现空指针异常,使代码更具有可读性.

5.2 Optional类的描述

  • 这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

5.3 Optuonal类使用总结

方法方法描述
of(T t)t为null时报空指针异常,否则创建一个Op实例
empty()创建一个空的Op实例
ofNullable(T t)t不为null时创建Op实例,否则创建空的Op实例
get()如果Op有值将其返回,否则抛出NoSuchElementException
isPresent()判断是否包涵值,返回boolean值
orElse(T t)如果调用对象包涵值,返回该值,否则返回t
orElseGet(Supplier s)如果调用对象包涵值,返回该值,否则返回s获取的值
map(Function f)如果有值对其处理,并返回处理后的Op,否则返回Op.empty()
flatMap(Function mapper)与map类似,要求返回值必须是Optional
filter(Predicate p)如果有值且满足断言条件返回该值得Op对象,否则返回空的Op对象

of(T t)

//工厂方法创建Optional实例
Optional<String> name = Optional.of("optional");
//传入参数为null,抛出NullPointerException.
Optional<String> someNull = Optional.of(null);

empty()

//Optional.empty() : 创建一个空的 Optional 实例
Optional<Object> empty = Optional.empty();

ofNullable(T t)

//创建一个值为'null'的Optional
Optional empty = Optional.ofNullable(null);

get()

//执行下面的代码会输出:No value present
try {
//在空的Optional实例上调用get(),抛出NoSuchElementException
System.out.println(empty.get());
} catch (NoSuchElementException ex) {
System.out.println(ex.getMessage());}

isPresent()

//isPresent() : 判断是否包含值
Optional<Employee> employees = Optional.ofNullable(null);
if(employees.isPresent()){ System.out.println("不为空");
}else{ System.out.println("为空");
}

ofElse(T t)

//如果值不为null,orElse方法返回Optional实例的值。
//如果为null,返回传入的消息。
//输出:There is no value!
System.out.println(empty.orElse("There is no value !"));
//输出:optional
System.out.println(name.orElse("There is some value!"));

orElseGet(Supplier s)

//orElseGet与orElse方法类似,区别在于orElse传入的是默认值
//orElseGet可以接受一个lambda表达式生成默认值。
//输出:Default Value
System.out.println(empty.orElseGet(() -> "Default Value"));
//输出:optional
System.out.println(name.orElseGet(() -> "Default Value"));

orElseThrow(Supplier s)

try {
//orElseThrow与orElse方法类似。与返回默认值不同
//orElseThrow会抛出lambda表达式或方法生成的异常
empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable e) {
//输出: No value present in the Optional instance
System.out.println(e.getMessage());
}
//ValueAbsentException定义class
ValueAbsentException extends Throwable {
public ValueAbsentException() {
super();
}
public ValueAbsentException(String msg) {
super(msg);
}
@Override
public String getMessage() { return "No value present in the Optional instance"; }}

map(Function f)


//map方法执行传入的lambda表达式参数对Optional实例的值进行修改。
//为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));

flatMap(Function mapper)

//flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。
//map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。
//但flatMap方法中的lambda表达式返回值必须是Optionl实例。
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));
//输出OPTIONAL

filter(Predicate p)

//filter方法检查给定的Option值是否满足某些条件。
//如果满足则返回同一个Option实例,否则返回空Optional。
Optional<String> longName = name.filter((value) -> value.length() > 6);
System.out.println(longName.orElse("The name is less than 6 characters"));
//输出optional

六、Stream

6.1 为什么java8加入Stream

  1. Stream是对集合对象功能的增强,专注于对集合对象进行各种非常便利、高效的聚合操作或者大批数据操作。
  2. 使代码更加简洁、易读。

6.2 什么是Stream

  1. 数据渠道,用于操作数据源所生成的元素序列。
  2. 像高级版本的迭代器,可以并行化操作。并行操作依赖于Fork/Join框架

6.3 Stream的使用

  1. 创建stream
  2. 中间操作:通过对个中间操作将stream转为另外一个stream
  3. 终止操作:获取结果,触发之前的懒操作的执行。
6.3.1 创建流
  1. 集合、数组、文件等都可以转成stream来处理。
  2. Collection接口提供Stream()方法。
  3. Map集合调用entrySet()方法转为Set 集合再转为Stream流。
6.3.2 中间操作
  1. 筛选与切片
方法描述
filter(Predicate)接收一个lambda,从流中排除某些元素
distinct()去重
limit(long maxSize)截断流,使其元素不超过给定数量
skip(long n)跳过元素,返回一个扔掉前n个元素的流,于limit互补
  1. 映射
方法描述
map(Function f)接收一个函数作为参数,该函数会被应用到每一个元素上,并将其映射成一个新的元素
mapToDouble(ToDoubleFunction f)
  1. 排序
方法描述
sorted()产生一个限流,按自然顺序排序
sorted(Comparator comp)
6.3.3 终止操作
  1. 查找于匹配
方法描述
boolean
allMatch(Predicate p)检查是否匹配所有元素
findFist()
count()
max(Comparator c)
forEach(Consumer c)
  1. 规约
方法描述
reduce(T iden,BinaryOperator b)可以将流中元素反复结合起来,得到一个值,返回T
reduce(BinaryOpertor b)返回Optional
  1. 收集
方法描述
collect(Collector c)将流转为其他形式,接收一个Collector实现,用于给stream中的元素做汇总的方法
  1. Collector静态方法
方法返回类型作用
toListList把流中元素收集到List
toSetSet
countingLong计算流中元素个数
joiningString链接流中的每个字符串
groupingByMap<K,List>根据某属性对流分组,属性为K,结果为V
partitioningByMap<Boolean,List>根据true或false进行分区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_42242792

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值