JDK 8 特性
Lambda表达式
本质上是一段匿名内部类 ,功效:减少无用的代码,以最简单的方式呈现。()、-、>、{ } 以上为 表达式
函数式接口
@FunctionInterface
,要求,接口中只有一个抽象方法,且加上此注解。
Consumer 《T》:消费型接口,有参无返回值
@Test
public void test(){
changeStr("hello",(str) -> System.out.println(str));
}
/**
* Consumer<T> 消费型接口
* @param str
* @param con
*/
public void changeStr(String str, Consumer<String> con){
con.accept(str);
}
Supplier 《T》:供给型接口,无参有返回值
@Test
public void test2(){
String value = getValue(() -> "hello");
System.out.println(value);
}
/**
* Supplier<T> 供给型接口
* @param sup
* @return
*/
public String getValue(Supplier<String> sup){
return sup.get();
}
Function 《T,R》::函数式接口,有参有返回值
@Test
public void test3(){
Long result = changeNum(100L, (x) -> x + 200L);
System.out.println(result);
}
/**
* Function<T,R> 函数式接口
* @param num
* @param fun
* @return
*/
public Long changeNum(Long num, Function<Long, Long> fun){
return fun.apply(num);
}
Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型
public void test4(){
boolean result = changeBoolean("hello", (str) -> str.length() > 5);
System.out.println(result);
}
/**
* Predicate<T> 断言型接口
* @param str
* @param pre
* @return
*/
public boolean changeBoolean(String str, Predicate<String> pre){
return pre.test(str);
}
Stream API()
使用流程:
- 创建stream
- 中间操作(过滤、map)
- 终止操作
创建:
// 1,校验通过Collection 系列集合提供的stream()或者paralleStream()
List<String> list = new ArrayList<>();
Strean<String> stream1 = list.stream();
// 2.通过Arrays的静态方法stream()获取数组流
String[] str = new String[10];
Stream<String> stream2 = Arrays.stream(str);
// 3.通过Stream类中的静态方法of
Stream<String> stream3 = Stream.of("aa","bb","cc");
// 4.创建无限流
// 迭代
Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
//生成
Stream.generate(() ->Math.random());
中间操作:
/**
* 筛选 过滤 去重
*/
emps.stream()
.filter(e -> e.getAge() > 10)
.limit(4)
.skip(4)
// 需要流中的元素重写hashCode和equals方法
.distinct()
.forEach(System.out::println);
/**
* 生成新的流 通过map映射
*/
emps.stream()
.map((e) -> e.getAge())
.forEach(System.out::println);
/**
* 自然排序 定制排序
*/
emps.stream()
.sorted((e1 ,e2) -> {
if (e1.getAge().equals(e2.getAge())){
return e1.getName().compareTo(e2.getName());
} else{
return e1.getAge().compareTo(e2.getAge());
}
})
.forEach(System.out::println);
Stream的终止操作:
/**
* 查找和匹配
* allMatch-检查是否匹配所有元素
* anyMatch-检查是否至少匹配一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任意元素
* count-返回流中元素的总个数
* max-返回流中最大值
* min-返回流中最小值
*/
Optional<Employee> opt = emps.stream().findFirst();
//Convert a Stream to List
List<String> result = emps.stream().collect(Collectors.toList());
实例:
// 1. 将list 分组,然后取每个list 中最大的一个数据
Map<String, VSiFinDirectEntity> latestStations = vSiFinHldDirectEntityList.parallelStream().collect(Collectors.toMap(VSiFinDirectEntity::getCenterCode, entity -> entity, (c1, c2) -> c1.getBeginDatetime().compareTo(c2.getBeginDatetime())> 0 ? c1 : c2));
vSiFinHldDirectEntityList = (List<VSiFinDirectEntity>) latestStations.values();
// 2. 取 diagnose 对象中的 DiagCode 生成 list集合。diagnose存在为空的可能
List<String> diagCodes = Optional.ofNullable(diagnoses).orElse(new ArrayList<VMrhpBaseDiagnoseBO>()).stream().map(s -> s.getDiagCode()).collect(Collectors.toList());
设计层面上:
抽象类是对事物的抽象,包括事物的属性方法在内,而接口是对行为的抽象仅限于 事物的行为。
抽象类是“是不是”的关系,而接口是“有没有”的关系
接口中的默认方法和静态方法
- 接口的默认方法与静态方法都可以写多个
public interface Interface {
default String getName() {
return "测试";
}
default String getAge() {
return "18";
}
static String getName2(){
return "zhangsan";
}
}
为什么要添加静态方法与默认方法 ? -> 为了接口的演化
- 默认方法:方便在进行进行早期代码合并时,处理兼容性问题,不用破坏原有的代码实现。
- 静态方法:方便进行将方法与接口进行绑定。如果方法实现上需要静态方法,其静态方法存放用接口中,比放在工具类中更合适
新时间日期API
类 | 说明 | 实例 |
---|---|---|
Instant | 瞬时实例 | Instant.now() -> 2014-01-14T08:33:33.379Z |
LocalDate | 本地日期,不包含具体时间 | LocalDate.now() -> 2014-01-14 |
LocalTime | 本地时间,不包含日期 | LocalTime.now() -> 16:33:33.369(格式:hh:mm:ss:nnn) |
LocalDateTime | 组合了日期和时间,但不包含时差和时区信息 | LocalDateTime.now() -> DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MMM-dd hh:mm:ss") -> arrivalDate.format(format) -> 日期(yyyy-MMM-dd hh:mm:ss) |
ZonedDateTime | 最完整的日期时间,包含时区和相对UTC或格林威治的时差 | |
YearMonth | 组合类,用于表示信用卡到期日、FD到期日、期货期权到期日等。还可以用这个类得到 当月共有多少天,YearMonth实例的lengthOfMonth()方法可以返回当月的天数,在判断2月有28天还是29天时非常有用。 | |
MonthDay | 类组合了月份和日,去掉了年,这意味着你可以用它判断每年都会发生事件 |
参考文章:
https://blog.csdn.net/qq_40366738/article/details/106222929
https://blog.csdn.net/qq_39505245/article/details/123779776