Java8

80 阅读4分钟

一. Lambda表达式

Lambda是一个匿名函数,Lambda允许把函数作为一个方法的参数

特征:
1.不需要声明参数类型,编译器统一识别参数值

2.一个参数无需定义圆括号,但多个参数需要定义圆括号

3.如果主题包含了一个语句,就不需要大括号

4.如果主体只有一个表达式返回值则编译器自动返回值,大括号需要指定表达式返回了一个数值

Lambda表达式只能引用final的外层局部变量

二. 方法引用和构造器引用

1.方法引用:若Lambda体内的内容有方法已经实现,可以使用方法引用

语法格式:

对象::实例方法名

类::静态方法名

类::实例方法名 x.equals(y) 可以直接用此

--Lambda体中调用方法的参数列表与返回值列表 要与函数式接口中抽象方法的函数列表和返回值类型保持一致

2.构造器引用

ClassName::new

需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。

  1. 函数式接口(有且仅有一个抽象方法,但是可以有多个非抽象方法的接口)

    可以用@FunctionalInterface来判断是否是函数式接口

    四大核心函数式接口

    1.Comsumer 消费性接口

    void accept(T t);

    2.Supplier 供给型接口

    T get();

    3.Function<T,R> 函数型接口

    R apply(T)

    4.Predicate 断言型接口

    boolean test(T t)

       Consumer<String> consumer = (x)-> System.out.println(x);
       consumer.accept("my message");
    ​
       Supplier<String> supplier = ()-> "my age is 5";
       System.out.println(supplier.get());
    ​
       Function<Integer,String> function = (x)-> "your age is ="+x;
       System.out.println(function.apply(5));
    ​
       Predicate<Integer> predicate = (x)->x>29;
       System.out.println(predicate.test(28));
    
  2. 接口增加默认方法(default void function())

接口可以有实现方法,而不需要实现类去实现其方法

5.Stream 流

5.1流是数据渠道,用于操作数据源所生成的元素序列。

(不会存储元素,不会改变源对象,延迟操作)

不同于Collection

1.中间操作都会返回流对象本身

2.集合操作都是通过Iterator或者For-each的方式显示的在集合外部进行迭代 --外部迭代

Stream提供了内部迭代,通过访问者模式(Visitor)实现

5.2操作

stream() 为集合创建串行流

parallelStream() 为集合创建并行流

创建操作 中间操作 终止操作

1.1创建操作

//1.Collection 的stream或parallelStream

List list = new ArrayList<>();

Stream str1 = list.stream();

//2.Arrays.stream

Employee[] emps = new Employee[10];

Stream str2 = Arrays.stream(emps);

//3.Stream 的静态方法of

Stream str3 = Stream.of("aa", "bb", "cc", "dd");

//4.创建无限流

//41迭代

Stream iterate = Stream.iterate(0, (x) -> x + 2);

iterate.limit(10)

.forEach(System.out::println);

//42

Stream generate = Stream.generate(() -> Math.random());

generate.limit(5).forEach(System.out::println);

1.2中间操作(不会执行任何操作,直到终止操作才执行全部操作 惰性求值)

筛选与切片

filter 过略元素

limit 截断流

skip 跳过

distinct 筛选 (通过元素的hashCode和equals去除重复)

1.3映射

map -接收lambda 将元素转化成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

flatMap -接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

add()和addAll()

1.4排序

sorted() -自然排序(Comparable)

softed(Comparator com) -定制排序

1.5终止操作

查找与匹配

allMatch

anyMatch

noneMatch

findFirst

findAny

count

max

min

1.6规约和收集

reduce - 将流中元素反复结合起来得到一个值

collect - 将流转化为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

工具类Collectors

6.Optional

Optional 是一个容器类,代表一个值存在或不存在。避免空指针。

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

/*
Optional.of(T t) 创建一个Optional实例
Optional.empty() 创建一个空的Optional实例
Optional.ofNullable(T t) 若t不为null,创建Optional实例,否则创建空实例
isPresent() 判断是否包含值
orElse(T t) 如果调用对象包含值,返回该值,否则返回t
map(Function f) 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
flatMap(Function mapper) 与map类似,要求返回值必须是Optional
*/
​
@Test
public void test03(){
Optional<Employee> op = Optional.ofNullable(new Employee("zc",30,122334));
Optional<String> s = op.map((e) -> e.getName());
System.out.println(s.get());
​
​
Optional<String> s1 = op.flatMap((e) -> Optional.of(e.getName()));
System.out.println(s1.get());
}
@Test
public void test02(){
Optional<Employee> op = Optional.ofNullable(null);
if(op.isPresent()){
System.out.println(op.get());
}
​
Employee emp = op.orElse(new Employee("aa",13,980.3));
System.out.println(emp);
​
op.orElseGet(()-> new Employee());
​
}
​
@Test
public void test01(){
Optional<Employee> employee = Optional.of(new Employee());
System.out.println(employee.get());
​
}

7.Date

LocalDate
LocalTime
LocalDateTime
--都是不可变类
//ZonedDate ZonedTime ZonedDateTime
@Test
public void test06(){
Set<String > set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);
​
LocalDateTime now = LocalDateTime.now(ZoneId.of("Europe/Tallinn"));
System.out.println(now);
​
}
​
//格式化时间 格式 DateTimeFormatter
@Test
public void test05(){
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(dtf));
​
}
​
//时间矫正器 TemporalAdjusters
//接口 TemporalAdjuster
@Test
public void test04(){
LocalDateTime ldt = LocalDateTime.now();
TemporalAdjuster next = TemporalAdjusters.next(DayOfWeek.SUNDAY);
LocalDateTime ldt2 = ldt.with(next);
System.out.println(ldt2);
​
LocalDateTime with = ldt.with((l) -> {
LocalDateTime ldt3 = (LocalDateTime) l;
DayOfWeek dayOfWeek = ldt3.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return ldt3.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return ldt3.plusDays(2);
}
return ldt.plusDays(1);
​
});
System.out.println(with);
​
}
​
​
//Duration 时间间隔
//period 日期间隔
@Test
public void test03(){
Instant ins1 = Instant.now();
Instant plus = ins1.plus(100, ChronoUnit.SECONDS);
Duration between = Duration.between(ins1, plus);
System.out.println(between.getSeconds());
}
​
//Instant 时间戳 -1970 1 1 0 0 0
@Test
public void test02(){
Instant now = Instant.now();//默认获取的UTC时区
System.out.println(now);
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
​
System.out.println(now.toEpochMilli());
}
​
​
//LocalDate LocalTime LocalDateTime
@Test
public void test01(){
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
​
LocalDateTime ldd = LocalDateTime.of(2021, 12, 15, 22, 52, 12);
System.out.println(ldd);
LocalDateTime ldp = ldd.plusYears(10);
System.out.println(ldp);
LocalDateTime dateminus = ldd.minusYears(10);
System.out.println(dateminus);
​
​
System.out.println(ldd.getYear());
System.out.println(ldd.getMonth().getValue());
System.out.println(ldd.getDayOfMonth());
}
​