Java8新特性
接口
首先是接口中能够定义default和statis方法体了,这样子就不用接口一改,下面的实现类都改了
默认方法提供了默认的行为,而静态方法提供了在接口级别上的通用功能。
和抽象类的区别还是有的
-
接口的方法是 public 修饰,变量是 public static final 修饰,默认是
public static final
修饰的,且不能修改。 -
abstract class 可以用其他修饰符
接口中的方法默认是 public
修饰的,不能修改为其他访问修饰符(如 private
、protected
)
lambda表达式
在lambda表达式中 说一下之前不熟悉的::的用法
这个::是用来引用方法的,可以把方法直接拿出来,也可以引用构造函数
如下用法
-
静态方法引用:
ClassName::staticMethodName
这种形式表示引用一个类的静态方法。例如,Math::max
表示引用Math
类的静态方法max
。 -
实例方法引用:
instance::instanceMethodName
这种形式表示引用一个对象的实例方法。例如,String::toUpperCase
表示引用String
对象的toUpperCase
方法。 -
构造方法引用:
ClassName::new
这种形式表示引用一个类的构造方法。例如,ArrayList::new
表示引用ArrayList
类的构造方法。
对于实例方法引用如下
class Counter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
Counter counter = new Counter();
//直接拿方法过来
Runnable runnable = counter::increment;
runnable.run();
System.out.println(counter.getCount());
遍历的时候拿方法
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
}
//用类去拿是Consumer
Consumer<Person> getX = Person::getX;
//用对象去拿是 Runnable
Runnable getX = person::getX;
List<Person> people = Arrays.asList(new Person("Alice"), new Person("Bob"), new Person("Charlie"));
people.forEach(Person::printName);
用类去拿是Consumer Consumer<Person> getX = Person::getX;
用对象去拿是 Runnable Runnable getX = person::getX;
Stream流
流用过一次后就不能用了,操作就会关闭
Optional
判断是否为空
Optional.ofNullable
true 不为空
public boolean isPresent() {
return value != null;
}
其他类型如下
//of():为非null的值创建一个Optional
Optional<String> optional = Optional.of("bam");
// isPresent():如果值存在返回true,否则返回false
optional.isPresent(); // true
//get():如果Optional有值则将其返回,否则抛出NoSuchElementException
optional.get(); // "bam"
//orElse():如果有值则将其返回,否则返回指定的其它值
optional.orElse("fallback"); // "bam"
//ifPresent():如果Optional实例有值则为其调用consumer,否则不做处理
optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b"
Date Time类
java.util.Date
既包含日期又包含时间,而 java.time
把它们进行了分离
LocalDateTime.class //日期+时间 format: yyyy-MM-ddTHH:mm:ss.SSS
LocalDate.class //日期 format: yyyy-MM-dd
LocalTime.class //时间 format: HH:mm:ss
所以用LocalDateTime
类更加简洁点
如下是日期转字符串
public void newFormat(){
//format yyyy-MM-dd
LocalDate date = LocalDate.now();
System.out.println(String.format("date format : %s", date));
//format HH:mm:ss
LocalTime time = LocalTime.now().withNano(0);
System.out.println(String.format("time format : %s", time));
//format yyyy-MM-dd HH:mm:ss
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(String.format("dateTime format : %s", dateTimeStr));
}
如下是字符串转日期
LocalDate date = LocalDate.of(2021, 1, 26);
LocalDate.parse("2021-01-26");
LocalDateTime dateTime = LocalDateTime.of(2021, 1, 26, 12, 12, 22);
LocalDateTime.parse("2021-01-26 12:12:22");
LocalTime time = LocalTime.of(12, 12, 22);
LocalTime.parse("12:12:22");
选of 或者pase都行,parse就直接转化了
判断过x天的日期
public void pushWeek(){
//一周后的日期
LocalDate localDate = LocalDate.now();
LocalDate after2 = localDate.plusWeeks(1);
System.out.println("一周后日期:" + after2);
//算两个日期间隔多少天,计算间隔多少年,多少月
LocalDate date1 = LocalDate.parse("2021-02-26");
LocalDate date2 = LocalDate.parse("2021-12-23");
Period period = Period.between(date1, date2);
System.out.println("date1 到 date2 相隔:"
+ period.getYears() + "年"
+ period.getMonths() + "月"
+ period.getDays() + "天");
//打印结果是 “date1 到 date2 相隔:0年9月27天”
//这里period.getDays()得到的天是抛去年月以外的天数,并不是总天数
//如果要获取纯粹的总天数应该用下面的方法
long day = date2.toEpochDay() - date1.toEpochDay();
System.out.println(date2 + "和" + date2 + "相差" + day + "天");
//打印结果:2021-12-23和2021-12-23相差300天
}
获取当月的第一天和最后一天
public void getDayNew() {
LocalDate today = LocalDate.now();
//获取当前月第一天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
// 取本月最后一天
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
//取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
//当年最后一天
LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear());
//2021年最后一个周日,如果用Calendar是不得烦死。
LocalDate lastMondayOf2021 = LocalDate.parse("2021-12- 31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
}
JDBC和java8的类型对应
现在 jdbc 时间类型和 java8 时间类型对应关系是
-
Date
--->LocalDate
-
Time
--->LocalTime
-
TimesSamp
--->LocalDateTime
时区转化
//当前时区时间
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("当前时区时间: " + zonedDateTime);
//东京时间
ZoneId zoneId = ZoneId.of(ZoneId.SHORT_IDS.get("JST"));
ZonedDateTime tokyoTime = zonedDateTime.withZoneSameInstant(zoneId);
System.out.println("东京时间: " + tokyoTime);
// ZonedDateTime 转 LocalDateTime
LocalDateTime localDateTime = tokyoTime.toLocalDateTime();
java8的merge()操作
原理就是将一个key 更新值(如果存在的话),并且将这两个value作函数操作。如果给定的key不存在,它就变成了 put(key, value)
如下图
HashMap<String, Integer> map = new HashMap<>();
map.put("1",1);
map.put("2",1);
map.put("3",1);
map.put("4",1);
map.merge("2",10,Integer::sum);
System.out.println(map.get("2"));
输出
11