默认接口方法
8开始,接口不只是一个只能声明方法的地方,还可声明方法时给方法一个默认实现,称为默认接口方法,这样所有实现该接口的子类都可持有该方法的默认实现。
//定义
public interface A{
default void method(){
sout("默认方法");
}
}
冲突解决
- 类或父类中显式声明的方法,其优先级高于所有的默认方法
- 如果1规则失效,则选择与当前类距离最近的具有具体实现的默认方法
- 如果2规则也失效,则需要显式指定接口 ```java public interface A {
/**
- 默认方法定义 */ default void method() { System.out.println(“A’s default method!”); }
}
public interface B extends A {
/**
* 默认方法定义
*/
default void method() {
System.out.println("B's default method!");
}
}
public class C implements A, B {
public static void main(String[] args) {
new C().method();
}
}
// 输出:B’s default method!;因B距离近。
<a name="xfwHv"></a>
### 流式数据处理
```java
//8之前
List<Integer> e = new ArrayList<>();
for(final Integer num: nums){
if(num % 2 == 0){
e.add(num);
}
}
//8
List<Integer> e = nums.stream().filter(a -> a % 2 == 0).collect(Collectors.toList());
//lambda表达式还原为匿名内部类
List<Integer> e = nums.stream().filter(new Predicate<Integer>(){
@Override
public boolean tt(Integer num){
return num%2==0;
}
}).collect(Collectors.toList());
//解释:stream()操作将集合转为流,filter()执行我们自定义的筛选,
//通过lambda表达式筛选偶数,然后collect()对结果进行封装处理,通过Collectors.toList()指定封装为一个集合。
flatMap与mapq区别
- flatMap是将流中每个值都转换成一个个流,然后再扁平化为一个流
//如 String[] strs = {"java","is","easy","to","use",} //返回一组非重复字符 List<String[]> disstr = Arrays.stream(strs).map(s -> s.split("")).distance().collect(Collectors.toList()); //结果 [j, a, v, a, 8] [i, s] [e, a, s, y] [t, o] [u, s, e] //正确 List<String[]> disstr = Arrays.stream(strs) .map(s -> s.split(""))//映射为Stream<String[]> .flatMap(Arrays::stream)//扁平化为 .distinct() .collect(Collectors.toList());
归约
```java //普通 int totalAge = students.stream() .filter(s -> “计算机科学”.equals(s.getMajor())) .maoToInt(Student::getAge) .sum(); //规约实现 int totalAge = students.stream() .filter(s -> “计算机科学”.equals(s.getMajor())) .map(Student””getAge) .reduce(0,(a,b) -> a+b); //进一步简化 int totalAge = students.stream() .filter(s -> “计算机科学”.equals(s.getMajor())) .map(Student””getAge) 。reduce(0,Integer::sum); //无初始值的重载版本,注意返回Optional OptionaltotalAge = students.stream() .filter(s -> “计算机科学”.equals(s.getMajor())) .map(Student””getAge) 。reduce(Integer::sum);//去掉初始值。 //普通 //规约实现
//普通 //规约实现
<a name="ZJdfI"></a>
### Optional类优雅判null
- NPE是一个运行时异常,if判断null即可。
- 良好的程序应该减少null,Optional,减少null的同时提升了美观度,不是代替null,而是对null判断的优雅实现。
- Optional是finall类,没实现任何接口,利用该类包装定义属性时,若有序列化需求,会出问题。
<a name="9boRa"></a>
#### 例子
```java
if(null == str){ return 0;}
return str.length();
//Java 8 中我们可以通过 "::" 关键字来访问类的构造方法,对象方法,静态方法。
return Optional.ofNullable(str).map(String::length).orElse(0);
//创建空对象
Optional<String> opstr = Optional.empty();
//创建对象,不允许为空
Optional<String> opstr = Optional,of(str);//为null抛出异常。
//创建对象,允许为空
Optional<String> opstr = Optional,ofNullable(str);//为null,创建空对象。
//
@Data
public class User {
/** 用户编号 */
private long id;
private String name;
private int age;
private Optional<Long> phone;
private Optional<String> email;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
//
User u = new User();
//获取name,null返回预设字符。
String name = Optional.ofNullable(u).map(User::getName).orElse("no name");
Lone phone = u.map(User::getPgone).map(Optional::get).orElse(-1L);
//flatMap可将返回的各个流扁平化为一个流。
String email = u.flatMap(User::getEmail).orElse("ee");
//Optional不能序列化
public class User implements Serializable{
/** 用户编号 */
private long id;
private String name;
private int age;
private Optional<Long> phone; // 不能序列化
private Optional<String> email; // 不能序列化
}
//解决
private long phone;
public Optional<Long> getPhone() {
return Optional.ofNullable(this.phone);
}
Lambda表达式
- 可将lambda表达式定义为一种简介、可传递的匿名内部类。
- lambda表达式本质是函数,不属于特定的类,但具备参数列表、函数主体、返回类型,以及能够抛出异常。
- 其次他是匿名的,lambda表达式没有具体的函数名称,lambda表达式可像参数一样传递,从而极大简化代码。
例子筛选过滤
```java //过滤苹果 //8之前,过滤接口实现
//过滤接口
@FunctionalInterface
public interface AppleFilter{
//筛选条件抽象
boolean accept(Apple apple);
}
//晒徐条件封装为接口
public static List
//匿名内部类
public static void main(String[] args){
List
List
//lambda简化
List