目录
4.1、函数式接口
4.1.1、内置接口
什么是函数式接口呢?
有且仅有一个抽象方法的接口就是函数式接口,并且可以通过在类上标注@FunctionalInterface注解进行检测。
四大内置函数式接口:
Supplier接口:供给型接口,无参有返回值的接口
public class Main {
public static void main(String[] args) {
printMax(() -> Math.max(10, 20));
}
public static void printMax(Supplier<Integer> supplier) {
Integer result = supplier.get();
System.out.println(result);
}
}
Consumer接口:消费型接口,有参无返回值的接口
public class Main {
public static void main(String[] args) {
printStr(s -> System.out.println(s.toUpperCase()));
}
public static void printStr(Consumer<String> consumer) {
consumer.accept("Hello,World");
}
}
public class Main {
public static void main(String[] args) {
printStr(s -> System.out.println(s.toUpperCase()), s -> System.out.println(s.toLowerCase()));
}
public static void printStr(Consumer<String> consumer1, Consumer<String> consumer2) {
consumer1.andThen(consumer2).accept("Hello,World");
}
}
Function接口:函数型接口,有参有返回值的接口,第一个参数为输入值,第二个参数为输出值
public class Main {
public static void main(String[] args) {
printNum(s -> Integer.parseInt(s));
}
public static void printNum(Function<String, Integer> function) {
Integer result = function.apply("10");
System.out.println(result);
}
}
public class Main {
public static void main(String[] args) {
Function<Integer, Integer> times2 = i -> i * 2;
Function<Integer, Integer> squared = i -> i * i;
//32,先执行apply(4),再4×4,然后16×2
System.out.println(times2.compose(squared).apply(4));
//64,先执行apply(4),再4×2,然后8×8
System.out.println(times2.andThen(squared).apply(4));
}
}
BiFunction接口:函数型接口,有参有返回值的接口,第一个参数为输入值,第二个参数为输入值,第三个参数为输出值
public class Main {
public static void main(String[] args) {
printSum((num1, num2) -> num1 + num2);
}
public static void printSum(BiFunction<Integer, Integer, Integer> biFunction) {
Integer result = biFunction.apply(10, 20);
System.out.println(result);
}
}
public class Main {
public static void main(String[] args) {
printSumAndMul((num1, num2) -> num1 + num2, num3 -> num3 * num3);
}
public static void printSumAndMul(BiFunction<Integer, Integer, Integer> biFunction1, Function<Integer, Integer> function2) {
Integer result = biFunction1.andThen(function2).apply(10, 20);
System.out.println(result);
}
}
Predicate接口:断定式接口,用于条件判断的场景
public class Main {
public static void main(String[] args) {
printResult(s -> s.contains("H"));
}
public static void printResult(Predicate<String> predicate) {
boolean result = predicate.test("Hello,World");
System.out.println(result);
}
}
public class Main {
public static void main(String[] args) {
printAnd(s -> s.contains("H"), s -> s.contains("W"));
printOr(s -> s.contains("H"), s -> s.contains("W"));
printNegate(s -> s.contains("H"));
}
public static void printAnd(Predicate<String> predicate1, Predicate<String> predicate2) {
boolean result = predicate1.and(predicate2).test("Hello,World");
System.out.println(result);
}
public static void printOr(Predicate<String> predicate1, Predicate<String> predicate2) {
boolean result = predicate1.or(predicate2).test("Hello,World");
System.out.println(result);
}
public static void printNegate(Predicate<String> predicate) {
boolean result = predicate.negate().test("Hello,World");
System.out.println(result);
}
}
4.1.2、方法引用
符号表示:::
符号描述:双冒号为方法引用运算符,而他所在的表达式被称为方法引用。
应用场景:如果Lambda表达式所要实现的方案,已经有其他方法存在相同的方案,那么则可以使用方法引用。
常见形式:
- 对象::方法名
Date date = new Date();
Supplier<Long> supplier = date::getTime;
Long time = supplier.get();
System.out.println(time);
- 类名::静态方法
Supplier<Long> supplier = System::currentTimeMillis;
Long time = supplier.get();
System.out.println(time);
- 类名::普通方法
Function<String, Integer> function = String::length;
Integer length = function.apply("Hello");
System.out.println(length);
- 类名::new 调用对象的构造器
Function<String, String> function = String::new;
String result = function.apply("Hello");
System.out.println(result);
- 数据类型[]::new 调用数组的构造器
Function<Integer, int[]> function = int[]::new;
int[] result = function.apply(10);
System.out.println(Arrays.toString(result));
4.2、时间工具类
4.2.1、LocalDate
描述:LocalDate类获取日期信息。例如:2021-07-14
LocalDate nowTime = LocalDate.now();
System.out.println(nowTime);//获取日期
System.out.println(nowDate.getYear());//获取当前日期的年份
System.out.println(nowDate.getMonth());//获取当前日期的月份对象
System.out.println(nowDate.getMonthValue());//获取当前日期的月份
System.out.println(nowDate.getDayOfWeek());//表示该对象表示的日期是本周星期几
System.out.println(nowDate.getDayOfMonth());//表示该对象表示的日期是本月第几天
System.out.println(nowDate.getDayOfYear());//表示该对象表示的日期是本年第几天
System.out.println(nowDate.withYear(1997));//修改当前对象的年份
System.out.println(nowDate.withMonth(12));//修改当前对象的月份
System.out.println(nowDate.withDayOfMonth(5));//修改当前对象在本月的日期
System.out.println(nowDate.withDayOfYear(30));//修改当前对象在本年的日期
System.out.println(nowDate.minusYears(1));//一年前
System.out.println(nowDate.minusMonths(1));//一月前
System.out.println(nowDate.minusWeeks(1));//一周前
System.out.println(nowDate.minusDays(1));//一天前
System.out.println(nowDate.plusYears(1));//一年后
System.out.println(nowDate.plusMonths(1));//一月后
System.out.println(nowDate.plusWeeks(1));//一周后
System.out.println(nowDate.plusDays(1));//一天后
LocalDate other = LocalDate.now().minusDays(1);//一天前
System.out.println(nowDate.isBefore(other));//比较当前对象日期是否在other对象日期之前
System.out.println(nowDate.isAfter(other));//比较当前对象日期是否在other对象日期之后
System.out.println(nowDate.isEqual(other));//比较当前对象日期是否与other对象日期相等
System.out.println(nowDate.compareTo(other));//比较当前对象日期与other对象日期在时间上的大小,为正,则nowDate晚
System.out.println(LocalDate.of(1991, 11, 11));//直接传入对应的年月日
System.out.println(LocalDate.of(1991, Month.NOVEMBER, 11));//相对上面只是把月换成了枚举
LocalDate birDay = LocalDate.of(1991, 11, 11);
System.out.println(LocalDate.ofYearDay(1991, birDay.getDayOfYear()));//第一个参数为年,第二个参数为当年的第多少天
System.out.println(LocalDate.ofEpochDay(birDay.toEpochDay()));//参数为距离1970-01-01的天数
System.out.println(LocalDate.parse("1991-11-11"));
System.out.println(LocalDate.parse("19911111", DateTimeFormatter.ofPattern("yyyyMMdd")));
4.2.2、LocalTime
描述:LocalTime类获取时间信息。例如:16:54:14.267
LocalTime nowTime = LocalTime.now();
System.out.println(nowTime);//获取时间
System.out.println(nowTime.getHour());//获取时
System.out.println(nowTime.getMinute());//获取分
System.out.println(nowTime.getSecond());//获取秒
System.out.println(nowTime.getNano());//获取纳秒
System.out.println(nowTime.withHour(19));//修改时
System.out.println(nowTime.withMinute(18));//修改分
System.out.println(nowTime.withSecond(17));//修改秒
System.out.println(nowTime.withNano(16));//修改纳秒
System.out.println(nowTime.minusHours(1));//一小时前
System.out.println(nowTime.minusMinutes(1));//一分钟前
System.out.println(nowTime.minusSeconds(1));//一秒钟前
System.out.println(nowTime.minusNanos(1));//一纳秒前
System.out.println(nowTime.plusHours(1));//一小时后
System.out.println(nowTime.plusMinutes(1));//一分钟后
System.out.println(nowTime.plusSeconds(1));//一秒钟后
System.out.println(nowTime.plusNanos(1));//一纳秒后
LocalTime other = LocalTime.now().minusHours(1);//一小时前
System.out.println(nowTime.isBefore(other));//比较当前时间是否在other对象时间之前
System.out.println(nowTime.isAfter(other));//比较当前对象时间是否在other对象时间之后
System.out.println(nowTime.compareTo(other));//比较当前对象时间与other对象时间在时间上的大小,为正,则nowTime晚
System.out.println(LocalTime.of(8, 20));//时分
System.out.println(LocalTime.of(8, 20, 30));//时分秒
System.out.println(LocalTime.of(8, 20, 30, 150));//时分秒纳秒
LocalTime mTime = LocalTime.of(8, 20, 30, 150);
System.out.println(LocalTime.ofSecondOfDay(mTime.toSecondOfDay()));//参数为距离当天零时的秒数
System.out.println(LocalTime.ofNanoOfDay(mTime.toNanoOfDay()));//参数为距离当天零时的纳秒数
System.out.println(LocalTime.parse("08:20:30"));
System.out.println(LocalTime.parse("082030", DateTimeFormatter.ofPattern("HHmmss")));
4.2.3、LocalDateTime
描述:LocalDateTime类获取日期时间信息。例如:2021-07-14T17:08:23.894
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println(nowDateTime);
System.out.println(nowDateTime.getYear());//获取年
System.out.println(nowDateTime.getMonthValue());//获取月
System.out.println(nowDateTime.getDayOfMonth());//获取日
System.out.println(nowDateTime.getHour());//获取时
System.out.println(nowDateTime.getMinute());//获取分
System.out.println(nowDateTime.getSecond());//获取秒
System.out.println(nowDateTime.getNano());//获取纳秒
System.out.println(nowDateTime.withYear(1997));//修改年
System.out.println(nowDateTime.withMonth(12));//修改月
System.out.println(nowDateTime.withDayOfMonth(5));//修改日
System.out.println(nowDateTime.withHour(19));//修改时
System.out.println(nowDateTime.withMinute(18));//修改分
System.out.println(nowDateTime.withSecond(17));//修改秒
System.out.println(nowDateTime.withNano(16));//修改纳秒
System.out.println(nowDateTime.minusYears(1));//一天前
System.out.println(nowDateTime.minusMonths(1));//一月前
System.out.println(nowDateTime.minusDays(1));//一天前
System.out.println(nowDateTime.minusHours(1));//一小时前
System.out.println(nowDateTime.minusMinutes(1));//一分钟前
System.out.println(nowDateTime.minusSeconds(1));//一秒钟前
System.out.println(nowDateTime.minusNanos(1));//一纳秒前
System.out.println(nowDateTime.plusYears(1));//一天后
System.out.println(nowDateTime.plusMonths(1));//一月后
System.out.println(nowDateTime.plusDays(1));//一天后
System.out.println(nowDateTime.plusHours(1));//一小时后
System.out.println(nowDateTime.plusMinutes(1));//一分钟后
System.out.println(nowDateTime.plusSeconds(1));//一秒钟后
System.out.println(nowDateTime.plusNanos(1));//一纳秒后
LocalDateTime other = LocalDateTime.now().minusHours(1);//一小时前
System.out.println(nowDateTime.isBefore(other));//比较当前时间是否在other对象时间之前
System.out.println(nowDateTime.isAfter(other));//比较当前对象时间是否在other对象时间之后
System.out.println(nowDateTime.isEqual(other));//比较当前对象时间是否与other对象时间相等
System.out.println(nowDateTime.compareTo(other));//比较当前对象时间与other对象时间在时间上的大小,为正,则nowDateTime晚
LocalDate birDay = LocalDate.of(1991, 11, 11);
LocalTime mTime = LocalTime.of(8, 20, 30, 150);
System.out.println(LocalDateTime.of(birDay, mTime));//参数为LocalDate和LocalTime
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20));
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20, 30));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20, 30));
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20, 30, 150));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20, 30, 150));
System.out.println(LocalDateTime.parse("1991-11-11T08:20:30"));
System.out.println(LocalDateTime.parse("1991-11-11 08:20:30", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
4.2.4、Instant
描述:Instant类由一个静态的工厂方法now()可以返回当前时间戳。
Instant instant = Instant.now();
System.out.println("当前时间戳是:" + instant);
Date date = Date.from(instant);
System.out.println("当前时间戳是:" + date);
instant = date.toInstant();
System.out.println("当前时间戳是:" + instant);
4.2.5、Period
描述:使用Period类计算日期时间差。
LocalDate today = LocalDate.now();
System.out.println(today);
LocalDate birthDate = LocalDate.of(1997, 12, 05);
System.out.println(birthDate);
Period period = Period.between(birthDate, today);//第二个参数减第一个参数
System.out.printf("年龄 : %d 年 %d 月 %d 日", period.getYears(), period.getMonths(), period.getDays());
4.2.6、Duration
描述:使用Duration类计算日期时间差。
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
LocalDateTime birthDate = LocalDateTime.of(1997, 12, 5, 20, 10, 5);
System.out.println(birthDate);
Duration duration = Duration.between(birthDate, today);//第二个参数减第一个参数
System.out.println(duration.toDays());//两个时间差的天数
System.out.println(duration.toHours());//两个时间差的小时数
System.out.println(duration.toMinutes());//两个时间差的分钟数
System.out.println(duration.toMillis());//两个时间差的毫秒数
System.out.println(duration.toNanos());//两个时间差的纳秒数
4.2.7、ChronoUnit
描述:ChronoUnit类可用于在单个时间单位内测量一段时间。
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
LocalDateTime birthDate = LocalDateTime.of(1997, 12, 5, 20, 10, 5);
System.out.println(birthDate);
System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));
System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
System.out.println("相差的百年数:" + ChronoUnit.CENTURIES.between(birthDate, today));
System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
4.2.8、时间格式化
字符串常用占位符:
y 四位数年份
M 月
d 日
H 时(24小时制)
h 时(12小时制)
m 分
s 秒
S 毫秒
线程安全的格式化:
- 将时间转为字符串:
LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String s = dtf.format(ldt);
- 将字符串转为时间:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse("2021-07-14 01:02:03", dtf);
线程不安全的格式化:
- 将时间转为字符串:
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
- 将字符串转为时间:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2021-07-14 01:02:03");
4.3、原子工具类
4.3.1、原子整数
AtomicBoolean类:
AtomicInteger类 、 AtomicLong类
4.3.2、原子引用
AtomicReference类:
AtomicStampedReference类:
AtomicMarkableReference类:
4.3.3、原子数组
AtomicIntegerArray类 、 AtomicLongArray类 、 AtomicReferenceArray类
4.3.4、字段更新器
AtomicIntegerFieldUpdater类 、 AtomicLongFieldUpdater类 、 AtomicReferenceFieldUpdater类
4.3.5、原子累加器
LongAdder类:
DoubleAdder类:
4.4、Optional类
Optional类主要解决的问题是臭名昭著的空指针异常(NullPointerException)。
4.4.1、创建对象
4.4.2、基本使用
基础版:
Optional<String> name = Optional.of("zhangsan");
if (name.isPresent()) {
String value = name.get();
System.out.println(value);
}
简化版:
Optional<String> name = Optional.of("zhangsan");
name.ifPresent(v -> System.out.println(v));
4.4.3、高级使用
filter:过滤操作
Optional<String> name = Optional.of("zhangsan");
Optional<String> optional = name.filter(s -> s.startsWith("zhang"));
optional.ifPresent(System.out::println);
map:映射操作
Optional<String> name = Optional.of("zhangsan");
Optional<String> optional = name.map(s -> s.toUpperCase());
optional.ifPresent(System.out::println);
flatMap:展开操作
Optional<String> name = Optional.of("zhangsan");
Optional<String> optional = name.flatMap(s -> Optional.of(s.toUpperCase()));
optional.ifPresent(System.out::println);
4.4.4、其他使用
如果 Optional 中有值则将其返回,否则返回 orElse 方法传入的参数。
String s = Optional.of("zhangsan").orElse("lisi");
System.out.println(s);
如果 Optional 中有值则将其返回,否则返回 orElseGet 方法传入的接口值。
String s = Optional.of("zhangsan").orElseGet(() -> "lisi");
System.out.println(s);
如果 Optional 中有值则将其返回,否则抛出 orElseThrow 方法传入的异常信息。
String s = Optional.of("zhangsan").orElseThrow(() -> new RuntimeException("空值"));
System.out.println(s);
4.5、Arrays类
描述:该类包含用于操作数组的各种方法。
4.6、Objects类
描述:该类包含用于操作对象的各种方法。