Java8 新特性 Java8 新增了一些新特性,详情请参考 ORACLE官网—JDK8新增功能
本篇文章仅整理出常用的几个特性,日常开发中可灵活使用。
Lambda 表达式 以前,我们可以使用Collections
工具类的 Comparator
比较器对给定的 List
集合进行排序。
1 2 3 4 5 6 7 8 9 List<String> names = Arrays.asList("peter" , "anna" , "mike" , "xenia" ); Collections.sort(names, new Comparator <String>() { @Override public int compare (String a, String b) { return b.compareTo(a); } });
现在有了 lambda 表达式以后,推荐使用以下方法比较大小:
1 2 Collections.sort(names, (String a, String b) -> b.compareTo(a)); names.sort((a, b) -> b.compareTo(a));
函数式接口 函数式接口(Functional Interface)就是只包含一个抽象方法的声明。针对该接口类型的所有 Lambda 表达式都会与这个抽象方法匹配。
@FunctionalInterface
保证接口内只有一个抽象方法。一旦添加了第二个抽象方法,编译器会立刻抛出错误提示。不过,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
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 package cn.lyf.lambda.demo3.a01;public class Demo01UserFunctionalInterface { public static void main (String[] args) { method((arr) -> { int sum = 0 ; for (int n : arr) { sum += n; } return sum; }); } public static void method (Operator op) { int [] arr = {1 , 2 , 3 , 4 }; int sum = op.getSum(arr); System.out.println("sum = " + sum); } } @FunctionalInterface interface Operator { int getSum (int [] arr) ; }
引用类的构造器及方法 Java 8 允许使用 ::
关键字来传递方法或者构造函数引用,无论如何,表达式返回的类型必须是 functional-interface。
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 27 28 29 30 public class LambdaClassSuper { LambdaInterface sf () { return null ; } } public class LambdaClass extends LambdaClassSuper { public static LambdaInterface staticF () { return null ; } public LambdaInterface f () { return null ; } void show () { LambdaInterface t = LambdaClass::staticF; LambdaClass lambdaClass = new LambdaClass (); LambdaInterface lambdaInterface = lambdaClass::f; LambdaInterface superf = super ::sf; LambdaInterface tt = LambdaClassSuper::new ; } }
访问变量 1 2 3 int i = 0 ;Collections.sort(strings, (Integer o1, Integer o2) -> o1 - i);
lambda 表达式可以引用外边变量,但是该变量默认拥有 final 属性,不能被修改,如果修改,编译时就报错。
Stream API Stream
依然不存储数据,不同的是它可以检索(Retrieve)和逻辑处理集合数据、包括筛选、排序、统计、计数等。可以想象成是 Sql 语句。
它的源数据可以是 Collection
、Array
等。由于它的方法参数都是函数式接口类型,所以一般和 Lambda 配合使用。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 @Test public void test () { List<String> strings = Arrays.asList("abc" , "def" , "gkh" , "abc" ); Stream<String> stringStream = strings.stream().filter(s -> "abc" .equals(s)); long count = stringStream.count(); strings.stream().forEach(System.out::println); Stream<String> limit = strings.stream().limit(1 ); String[] array = limit.toArray(String[]::new ); Stream<String> map = strings.stream().map(s -> s + "22" ); strings.stream().sorted().forEach(System.out::println); Stream.of(33 , 22 , 11 , 55 ).sorted((o1, o2) -> o2 - o1).forEach(System.out::println); Stream.of(new Person ("刘德华" , 58 ), new Person ("张学友" , 56 ), new Person ("张学友" , 56 ), new Person ("黎明" , 52 )) .distinct() .sorted(Comparator.comparingInt(Person::getAge)) .forEach(System.out::println); List<String> collect = strings.stream().filter(string -> "abc" .equals(string)).collect(Collectors.toList()); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining("," )); List<Integer> number = Arrays.asList(1 , 2 , 5 , 4 ); IntSummaryStatistics statistics = number.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("列表中最大的数 : " +statistics.getMax()); System.out.println("列表中最小的数 : " +statistics.getMin()); System.out.println("平均数 : " +statistics.getAverage()); System.out.println("所有数之和 : " +statistics.getSum()); List<String> strings2 = Arrays.asList("xyz" , "jqx" ); Stream.concat(strings2.stream(),strings.stream()).count(); Stream stream = strings.stream(); stream.limit(2 ); stream.forEach(System.out::println); stream.limit(2 ).forEach(System.out::println); }
Date-Time API 日期格式化
Java8 之前:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public void oldFormat () { Date now = new Date (); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd" ); String date = sdf.format(now); System.out.println(String.format("date format : %s" , date)); SimpleDateFormat sdft = new SimpleDateFormat ("HH:mm:ss" ); String time = sdft.format(now); System.out.println(String.format("time format : %s" , time)); SimpleDateFormat sdfdt = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ); String datetime = sdfdt.format(now); System.out.println(String.format("dateTime format : %s" , datetime)); }
Java8 之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void newFormat () { LocalDate date = LocalDate.now(); System.out.println(String.format("date format : %s" , date)); LocalTime time = LocalTime.now().withNano(0 ); System.out.println(String.format("time format : %s" , time)); LocalDateTime dateTime = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" ); String dateTimeStr = dateTime.format(dateTimeFormatter); System.out.println(String.format("dateTime format : %s" , dateTimeStr)); }
获取指定日期
1 2 3 4 5 6 7 8 9 10 11 12 13 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()); LocalDate lastMondayOf2021 = LocalDate.parse("2021-12-31" ).with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY)); }