一、Java 8 中的Interface接口
Java 8 中,接口方法除了可以定义抽象方法和常量外,还可以定义default默认方法和static静态方法。实现类可以不必覆写default(),静态方法用接口名调用。
二、日期时间
Java 8在java.time包下包含日期和时间API。
1、获取当前日期和时间
public class Demo09 {
public static void main(String[] args) {
//获取当前日期
LocalDate date = LocalDate.now();
//获取当前日期
LocalTime time = LocalTime.now().withNano(0);//去掉毫秒
//获取当前日期和时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(String.format("当前日期:%s", date));//当前日期:2023-08-20
System.out.println(String.format("当前时间:%s", time));//当前时间:11:36:09
System.out.println(String.format("当前日期时间:%s", dateTime));//当前日期时间:2023-08-20T11:36:09.509
System.out.println();
//类型转换
//字符串=>LocalDate
String strDate = "2023-08-20";
date = LocalDate.parse(strDate);
System.out.println(String.format("指定日期:%s", date));
//整数值=>LocalDate
date = LocalDate.of(2023, 8, 15);
System.out.println(String.format("指定日期:%s", date));
}
}
2、计算日期
public class Demo10 {
public static void main(String[] args) {
//获取当前时间
LocalDate now = LocalDate.now();
System.out.println(now.plus(1, ChronoUnit.WEEKS));//一周后的日期
System.out.println(now.plus(-1, ChronoUnit.WEEKS));//一周前的日期
System.out.println(now.plus(10, ChronoUnit.DAYS));//计算10天后的日期
//计算两个日期间隔:多少年,多少月,多少天
LocalDate date1 = LocalDate.parse("2020-01-21");
LocalDate date2 = LocalDate.parse("2021-08-17");
Period result = Period.between(date1, date2);
System.out.printf("间隔%d年,%d月,%d天",result.getYears(),result.getMonths(),result.getDays());
//计算两个日期间隔:多少天
long days = date1.toEpochDay() - date2.toEpochDay();
System.out.println("间隔"+days+"天");
}
}
3、获取指定日期
public class Demo11 {
public static void main(String[] args) {
//当前日期
LocalDate today = LocalDate.now();
//获取当月第一天
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("当月第一天 :"+firstDayOfMonth);
//获取当月最后一天
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("当月第一天 :"+lastDayOfMonth);
//下个月的第一天,在当月最后一天的基础上+1
System.out.println(today.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1));
//本月的最后一个星期一
System.out.println(today.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY)));
}
}
三、Lambda表达式
lambda表达式本质是一个匿名函数,它表达的是接口方法的实现,这个接口是函数式接口。与函数式接口搭配使用,可以简化代码的编写。
语法格式:(参数)->{逻辑代码}
四、函数式接口(@FunctionInterface)
1、函数式接口:在类上标注@FunctionInterface注解且只有一个抽象方法的接口,可以使用Lambda表达式进行实现。
对数组进行排序:
public class Demo01 {
public static void main(String[] args) {
//对集合进行排序
List<String> list = Arrays.asList("ab","cba","asdfg","cab","cacsvdvdvs");
//方式1:匿名实现类
list.sort(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
if(s1.length() == s2.length()) {
return s1.compareTo(s2);
}
return s1.length() - s2.length();
}
});
//方式2:lambda表达式(描述接口的实现)实现Comparator接口
//接口为函数式接口的可以用lambda表达式
list.sort(
//Comparator:函数式接口,只有一个compare抽象方法
//s1,s2:compare()的参数
(s1,s2)->{
//排序逻辑
if(s1.length() == s2.length()) {
return s1.compareTo(s2);
}
return s1.length() - s2.length();
}
);
System.out.println(list);
}
}
对集合进行遍历:
//集合遍历
public class Demo02 {
public static void main(String[] args) {
List<String> langList = Arrays.asList("Basic","QBasic","c","c++","PowerBuilder","Visual Basic");
//方式1:用forEach遍历集合
for (String lang : langList) {
System.out.println(lang);
}
//方式2:使用Lambda表达式遍历集合
langList.forEach((lang)->{
System.out.println(lang);
});
}
}
2、Java 8 中有一个包(java.util.function)专门放函数式接口,此包下的所有接口上都有@FunctionInterface注解,提供函数式接口。
Predicate接口:只有一个参数的且返回值为布尔值的断言型接口。该接口中包含多种default修饰的默认方法来进行多种条件的过滤。
//Predicate接口:抽象方法test():传入一个参数,返回布尔值,用于对逻辑代码进行判断的
public class Demo03 {
public static void main(String[] args) {
//List集合
List<String> langList = Arrays.asList("Basic","QBasic","c","c++","PowerBuilder","Visual Basic","c#");
//进行多种条件的过滤
//1.判断长度是否等于5
Predicate<String> predicate1 = (lang)->{return lang.length() == 5;};
langList.forEach((list)->{ //对集合进行遍历
System.out.println(list+"是否符合条件"+predicate1.test(list));//对每个元素进行"规则"判断
});
//2.判断内容是否存在其他字符(例:+,#,空格)
Predicate<String> predicate2 = (lang)->{
//遍历每个元素
for(int i=0;i<lang.length();i++) {
if(!Character.isLetter(lang.charAt(i))) {
return false;
}
}
return true;
};
langList.forEach((list)->{
System.out.println(list+"是否符合条件"+predicate2.test(list));
});
//3.逻辑关系组合
//逻辑与(and):两边都成立才为真
Predicate<String> predicate3 = predicate1.and(predicate2);
langList.forEach((list)->{
System.out.println(list+"是否符合条件"+predicate3.test(list));
});
//逻辑或(or):两个有一个成立就为真
Predicate<String> predicate4 = predicate1.or(predicate2);
langList.forEach((list)->{
System.out.println(list+"是否符合条件"+predicate4.test(list));
});
//逻辑非(negate):对结果取反
Predicate<String> predicate5 = predicate1.negate();
langList.forEach((list)->{
System.out.println(list+"是否符合条件"+predicate5.test(list));
});
}
}
Function接口:只有一个参数且返回一个结果的接口。该接口中提供了将多个函数组合一起的方法。
//Function接口:apply():传入一个参数(泛型),返回一个结果(泛型)
public class Demo04 {
public static void main(String[] args) {
List<String> langList = Arrays.asList("Basic","QBasic","c","c++","PowerBuilder","Visual Basic","c#");
//功能1:转换成小写
Function<String,String> fun1 = (lang)->{
System.out.println("fun1");
return lang.toLowerCase();
};
//功能2:加书名号(《》)
Function<String , String> fun2 = (lang)->{
System.out.println("fun2");
return String.format("《%s》", lang);
};
//组合:将功能1和功能2组合
//andThen():谁调andThen(),谁先执行
Function<String , String> fun3 = fun1.andThen(fun2);//先fun1再fun2
//compose():谁调compose(),谁后执行
Function<String , String> fun4 = fun1.compose(fun2);//先fun2再fun1
}
}
Comparator接口:传入两个参数且返回一个比较结果的比较器接口。该接口中提供了比较器的组合,反转等方法。
//Comparator接口:compare():传入两个参数
public class Demo05 {
public static void main(String[] args) {
List<String> langList = Arrays.asList("Basic","QBasic","c","c++","PowerBuilder","Visual Basic","c#","java");
//比较规则1:按照内容比较(ASCII)
Comparator<String> comp1 = (x,y)->{
return x.compareTo(y);
};
//比较规则2:按照长度比较
Comparator<String> comp2 = (x,y)->{
return x.length() - y.length();
};
//比较规则3:先内容比较,再长度比较
Comparator<String> comp3 = comp1.thenComparing(comp2);
//比较规则4:按照内容的降序
Comparator<String> comp4 = comp1.reversed();
//排序
langList.sort(comp4);
System.out.println(langList);
}
}