[toc]

image-20200923231111293

image-20200923231111293

Java8新特性

Lamda表达式

λ表达式:

本质上也是函数式编程:

java

1
2
3
(params) -> expression[表达式]
(params) -> statement[语句]
(params) -> {statements}
  • 使用原因
    1. 避免匿名内部类过多
    2. 代码看上去简洁
    3. 去掉了冗余的代码,留下核心逻辑
  • 使用前提:
    1. 一定是Function Interface(函数式接口) — Function Interface定义: 任何接口如果只包含唯一一个抽象方法, 那么这就是个函数式接口. 例如 Runnable

例子:

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 写一个函数式接口
public Interface TestInterface{
public void testmethod();
}

// 用lamda创建接口对象
public static void main(String[] args){
// 匿名内部类实现 ,(我觉得Lamda表达式是匿名内部类的简化)
new TestInterface(){
// 重写方法
@Override
public void testmethod() {
// 代码.....
}
}.testmethod();//当然有参数的就可以添加参数
/*----------------------------------------------------*/
// Lamda表达式
//Interface test1 = (参数)->{方法体};
Interface test1 = () -> {
// 代码....
System.out.println(1);
};
a.testmethod();
}

java四个函数式接口

函数式接口 参数类型 返回值 用途
1 Consumer 消费型接口 T(泛型) void 对类型为T的对象应用操作
2 Supplier 供给型接口 T 安徽类型为T的对象
Function<T, K> 函数型 T R 参数有两个T和R – R.apply(T t)
4 Prediction 判断断定型接口 T Boolen 确定类型为T的对象是否满足约束,并且返回Boolean值
5 BiFunction<T,U,R> 可以传递两个参数的函数型接口 T,U R 可以传递两个参数
6 UnaryOperator Function的子接口 T T 对类型为T的对象进行操作 返回 操作后的T
7 BinaryOperator BiFunction子接口 T, T T 二元运算
8 BiConsumer<T, U> T U void
9 ToIntFunction ToLongFunction ToDoubleFunction T int Long double 传参数返回不同类型数值
10 IntFunction LongFunction DoubleFunction int Long double R 不同参数类型返回R

Java巧用lambda,使用函数式接口 和lambda 可以让程序异步执行 (另外写一下) 可以看这里

方法引用

若lambda体中的方法内容被实现了 就可以用方法引用的方式实现

  • 对象::实例方法名
  • 类::静态方法
  • 类::实例方法

使用 方法引用的方法的 ==方法的参数和返回值== 一定要和对应接口中 ==方法的参数和返回值==相等

构造方法: 类A::new 会根据接口的 返回值和参数 自动匹配构造器

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public static void main(String[] args) {
method(StreamDemo::_TEST);
}

private static String _TEST(Object o) {
System.out.println("操作1");
return "000";
}

public static void method(MyFunction s) {
System.out.println(s.apply(new Object()).toString() + "real");
}
}
out:
/*操作1
000real*/

stream流计算

流式计算

在项目中数据存储在数据库 集合等地方. 数据的处理就要交给流来计算

操作步骤

  1. 创建Stream流

根据数据源 集合 数组中创建

  1. 根据API操作数据

一个操作链进行选择排序,,,

  1. 结束/终止操作

执行操作了链条产生结果 可以使用java7的try-with-resources

API看这里

举个🌰

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// id,age,name.major
class Student {}
public static void main(String[] args) {
Student s1 = new Student(1, 12, "sjs", "jsj");
Student s2 = new Student(2, 13, "zs", "dzx");
Student s3 = new Student(3, 14, "ls", "dzx");
Student s4 = new Student(4, 15, "ww", "xx");
Student s5 = new Student(5, 16, "lb", "dzx");
Student s6 = new Student(6, 17, "hhh", "jsj");
List<Student> students = Arrays.asList(s1, s2, s3, s3, s4, s5, s6);
// 根据集合创建一个流并操作
/*
* 去重
* 找到id是偶数的
* age 大于14的
* 逆序排列
* */
Stream<Student> stream = students.stream().
distinct().
filter((a) -> a.getId() % 2 == 0).
filter(a -> a.getAge() > 14).
map(a -> a.setName(a.getName().toUpperCase())).
sorted((a, b) -> b.getId() - a.getId());

stream.forEach(System.out::println);
}

时间

  1. 时间

image-20211230165223713

image-20211230165237091

image-20211230165522323

Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API: Local(本地) − 简化了日期时间的处理,没有时区的问题。 Zoned(时区) − 通过制定的时区处理日期时间的时区转换。

其他关键API ●Instant 它代表的是时间戳,比如2021-12-04T10:18:12.232Z,这可以从java.time.Clock类中获取,像这样: Instant current = Clock.system(ZoneId.of(“Asia/Tokyo”)).instant(); ●LocalDate 它表示的是不带时间的日期,比如2021-12-04。它可以用来存储生日,周年纪念日,入职日期等。 ●LocalTime - 它表示的是不带日期的时间,比如12:00:00 ●LocalDateTime - 它包含了时间与日期,不过没有带时区的偏移量 ●ZonedDateTime - 这是一个带时区的完整时间,它根据UTC/格林威治时间来进行时区调整

​ Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。对比老的API存在以下优势:

新的时间与日期API中的所有类都是不可变且线程安全的,这与之前的Date与Calendar API中的恰好相反。

Instant 的精确度更高,可以精确到纳秒级。

Duration 可以便捷得到时间段内的天数、小时数等。

LocalDateTime 能够快速地获取年、月、日、下一月等。

TemporalAdjusters 类中包含许多常用的静态方法,避免自己编写工具类

LocalDate

// 获取当前年月日 LocalDate localDate = LocalDate.now(); // 构造指定的年月日 LocalDate localDate1 = LocalDate.of(2021, 12, 4);

// 获取年、月、日、星期几 int year = localDate.getYear(); int year1 = localDate.get(ChronoField.YEAR);

Month month = localDate.getMonth(); int month1 = localDate.get(ChronoField.MONTH_OF_YEAR); int day = localDate.getDayOfMonth(); int day1 = localDate.get(ChronoField.DAY_OF_MONTH);

DayOfWeek dayOfWeek = localDate.getDayOfWeek(); int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);

1
2
3
4
计算值
localDate.plusDays(1);
localDate.plusMonths(1);
localDate.plusYears(1);

LocalDate localDate = LocalDate.of(2021, 12, 4); String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE); String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println(“s1:” + s1); System.out.println(“s2:” + s2); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(“获取当前时间:” + localDateTime); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:MM:SS”); String s = localDateTime.format(formatter); System.out.println(“格式化当前时间:” + s); s1:20211204 s2:2021-12-04 获取当前时间:2021-12-04T10:32:36.520 格式化当前时间:2021-12-04 10:32:36

LocalTime

// 创建 LocalTime LocalTime localTime = LocalTime.of(10, 18, 12); LocalTime localTime1 = LocalTime.now();

// 获取小时 int hour = localTime.getHour(); int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);

// 获取分 int minute = localTime.getMinute(); int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);

// 获取秒 int second = localTime.getMinute(); int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);

LocalDateTime

// 创建 LocalDateTime LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime localDateTime1 = LocalDateTime.of(2021, Month.SEPTEMBER, 10, 14, 46, 56); LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime); LocalDateTime localDateTime3 = localDate.atTime(localTime); LocalDateTime localDateTime4 = localTime.atDate(localDate); // 获取LocalDate LocalDate localDate2 = localDateTime.toLocalDate(); // 获取LocalTime LocalTime localTime2 = localDateTime.toLocalTime();

Instant

// 创建Instant对象 Instant instant = Instant.now(); // 获取秒数 long currentSecond = instant.getEpochSecond(); // 获取毫秒数 long currentMilli = instant.toEpochMilli();

ZonedDateTime

ZonedDateTime类,用于处理带时区的日期和时间。ZoneId表示不同的时区。 Set allZoneIds=ZoneId.getAvailableZoneIds();

创建时区: ZoneId zoneId=ZoneId.of(“Asia/Shanghai”); 把LocalDateTime转换成特定的时区: ZonedDateTime zonedDateTime=ZonedDateTime.of(LocalDateTime.now(), zoneId);

获取当前时区: ZoneId z=ZoneId.systemDefault(); 获取日期时间: ZonedDateTime dd = ZonedDateTime.now(); ZonedDateTime date1 = ZonedDateTime.parse(“2021-12-04T10:15:30+05:30[Asia/Shanghai]”);

Duration

// Duration.between()方法创建 Duration 对象 LocalDateTime from = LocalDateTime.of(2021, Month.JANUARY, 1, 00, 0, 0); LocalDateTime to = LocalDateTime.of(2021, Month.SEPTEMBER, 12, 14, 28, 0);

Duration duration = Duration.between(from, to); // 表示从 from 到 to 这段时间 long days = duration.toDays(); // 这段时间的总天数 long hours = duration.toHours(); // 这段时间的小时数 long minutes = duration.toMinutes(); // 这段时间的分钟数 long seconds = duration.getSeconds(); // 这段时间的秒数 long milliSeconds = duration.toMillis(); // 这段时间的毫秒数 long nanoSeconds = duration.toNanos(); // 这段时间的纳秒数

1
AbstractProcessor(注解处理器)