1.interface接口
java8中,接口中除了可以定义抽象方法外还可以定义默认方法和静态方法。
- default修饰的默认方法属于实例方法,可以被实现类调用和重写。
- static修饰的静态方法,不能被子类继承,只能通过interface接口名称调用。
2.Lambda表达式
lambda本质上是一种匿名函数,用于实现函数式编程风格。
作用:可以使代码变得更简洁紧凑。
2.1案例
- 传统方法
list.sort(new Comparator<String>() { @Override public int compare(String o1, String o2) { if(o1.length()==o2.length()){ return o1.compareTo(o2); } return o1.length()-o2.length(); } });
- lambda表达式
list.sort( (o1,o2)->{ if(o1.length()==o2.length()){ return o1.compareTo(o2); } return o1.length()-o2.length(); } );
3函数式接口
定义:该接口中只有一个抽象方法,其他方法为默认方法或者静态方法。可以使用lambda实现函数式编程。函数式接口都用注解@FunctionalInterface
3.1Predicate
只有一个参数,返回值是布尔类型的断言型接口。
源码:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
案例:
Predicate<String> predicate1=(l)->{return l.length()==3;};
Predicate<String> predicate2=(l)->{
for(int i=0;i<list.size();i++){
if(!Character.isLetter(list.get(i).charAt(i))){
return false;
}
}
return true;
};
// 逻辑与
Predicate<String> predicate3=predicate1.and(predicate2);
//遍历
list.forEach(x->{
System.out.println(x+"是否符合条件"+predicate3.test(x));
});
// 非
Predicate<String> negate = predicate1.negate();
// 逻辑或
Predicate<String> or = predicate1.or(predicate2);
3.2Function
接收一个参数并生成结果。
源码:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
案例:
//map采用Fucation接口封装
list.stream().map((l)->{return l.length();})//长度
.forEach((l)->{//遍历
System.out.println(l);
});
list.stream().map((l)->{
return l.toUpperCase();})//大写
.forEach((l)->{//遍历
System.out.println(l);
});
Function<String,String> function=(l)->{
System.out.println("function1");
return l.toUpperCase();};
Function<String,String> function2=(l)->{
System.out.println("function2");
return String.format("<%s>",l);};
// 组合条件
Function<String,String> function3=function.andThen(function2);
Function<String,String> function4=function.compose(function2);
list.stream().map(function3).forEach((l)->{
System.out.println(l);
});
3.3Comparator
比较器接口,用于比较特定元素值的大小。java8中添加了多个default方法用于比较器合并、反转等。
源码:
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
default <U> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
return thenComparing(comparing(keyExtractor, keyComparator));
}
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
return thenComparing(comparingInt(keyExtractor));
}
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
return thenComparing(comparingLong(keyExtractor));
}
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
return thenComparing(comparingDouble(keyExtractor));
}
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
}
案例:
Comparator<String> comparator1=(x,y)->{return x.compareTo(y);};
// 按长度比
Comparator<String> comparator2=(x,y)->{return x.length()-y.length();};
// 按内容和长度的组合比
Comparator<String> comparator3=comparator1.thenComparing(comparator2);
Comparator<String> comparator4=comparator2.thenComparing(comparator1);
// 按长度的降序比
Comparator<String> comparator5=comparator2.reversed();
//比较
list.sort(comparator3);
4.Stream流
4.1并行流和串行流
// 串行流
// values.stream().sorted().count();
// 并行流
values.parallelStream().sorted().count();
4.2流的常用方法
stream流的操作分为中间操作和最终操作。
中间操作有:filter(过滤)、sorted(排序) 、map(映射)
long count= Arrays.stream(array).filter((letter)->{return letter.length()==3;}).count();
System.out.println(count);
String s= Arrays.stream(array)
.distinct()//去重
.sorted((x,y)->{//排序
if(x.length()==y.length()){
x.compareTo(y);
}
return y.length()-x.length();
})
.findFirst().get();//得到第一个元素
list.stream().map((l)->{return l.toUpperCase();}).forEach(System.out::print);
最终操作:match( 匹配)、count(计数)、collect(收集)、statistics(统计)
boolean isContains1=list.stream().anyMatch((letter)->{return letter.length()==2;});
boolean isContains2=list.stream().allMatch((letter)->{return letter.length()==2;});
boolean isContains3=list.stream().noneMatch((letter)->{return letter.length()==2;});
String[] array={"a","ab","abc","abcd","abcde","a","ab","aa"};
// 收集成map集合
Map<String, Integer> map = Arrays.stream(array).distinct().collect(Collectors.toMap((letter) -> {
return letter;
},
(letter) -> {
return letter.length();
}));
// 去重并收集成set集合
// set集合会自己去除重复元素
Set<String> letterSet= Arrays.stream(array)
.collect(Collectors.toSet());
public static void main(String[] args) {
// 分组
List<String> letterList= Arrays.asList("a","abs","abc","bd","bcd","bdd","cc","cf","cr");
Map<Character,List<String>> map=letterList.stream()
.collect(Collectors.groupingBy(s->s.charAt(0)));
System.out.println(map);
List<Integer> list= Arrays.asList(1,2,3,4,5,6);
// 先将普通流转换为数值流
Stream<Integer> stream=list.stream();
IntStream intStream=stream.mapToInt(x->x);
IntSummaryStatistics summaryStatistics=intStream.summaryStatistics();
System.out.println("最大值:"+summaryStatistics.getMax());
System.out.println("最小值:"+summaryStatistics.getMin());
System.out.println("平均值:"+summaryStatistics.getAverage());
System.out.println("累加值:"+summaryStatistics.getSum());
System.out.println("总个数:"+summaryStatistics.getCount());
5.日期时间
LocalDateTime 日期+时间
LocalDate日期
LocalTime时间
5.1格式化
// 获取当前的日期和时间
LocalDate date=LocalDate.now();
LocalTime time=LocalTime.now();
LocalDateTime localDateTime=LocalDateTime.now();
5.2字符串日期互转
//类型转换
// 字符串->localDate
String s="2023-08-15";
date=LocalDate.parse(s);
System.out.println("指定日期:"+date);
// 整数值->LocalDate
date=LocalDate.of(2023,8,12);
System.out.println("指定日期:"+date);
5.3日期计算
十天前与十天后
LocalDate localDate=LocalDate.now();
LocalDate datebefore=localDate.plus(-10, ChronoUnit.DAYS);
System.out.println(datebefore);
LocalDate dateafter=localDate.plus(10,ChronoUnit.DAYS);
System.out.println(dateafter);
间隔天数
//间隔天数
LocalDate localDate1=LocalDate.parse("2022-11-23");
LocalDate localDate2=LocalDate.parse("2023-08-17");
Period period= Period.between(localDate1,localDate2);
System.out.println(period.getYears()+"年"+period.getMonths()+"月"+period.getDays()+"天");
long day=localDate2.toEpochDay()-localDate1.toEpochDay();
System.out.println("相差"+day+"天");
5.4获取指定日期
/当前日期
LocalDate today=LocalDate.now();
// 获取本月第一天
LocalDate firstDayOfMonth=today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("本月第一天:"+firstDayOfMonth);
// 获取本月最后一天
LocalDate lastDayOfMonth=today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("本月最后一天:"+lastDayOfMonth);
LocalDate nextMonthfirstDay=today.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1);
System.out.println("下月第一天:"+nextMonthfirstDay);
LocalDate lastDayOfYear=today.with(TemporalAdjusters.lastDayOfYear());
System.out.println("本月最后一天:"+lastDayOfYear);
LocalDate date=today.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY));
System.out.println("最后一个周五:"+date);