jdk8新特性

https://www.runoob.com/java/java8-new-features.html

Java 8 新特性

Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。


新特性

Java8 新增了非常多的特性,我们主要讨论以下几个:

  • Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。

  • 方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

  • 默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。

  • 新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。

  • Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。

  • Date Time API − 加强对日期与时间的处理。

  • Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。

  • Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

更多的新特性可以参阅官网:What's New in JDK 8

在关于 Java 8 文章的实例,我们均使用 jdk 1.8 环境,你可以使用以下命令查看当前 jdk 的版本:

$ java -version
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

编程风格

Java 8 希望有自己的编程风格,并与 Java 7 区别开,以下实例展示了 Java 7 和 Java 8 的编程格式:

Java8Tester.java 文件代码:

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;
 
public class Java8Tester {
   public static void main(String args[]){
   
      List<String> names1 = new ArrayList<String>();
      names1.add("Google ");
      names1.add("Runoob ");
      names1.add("Taobao ");
      names1.add("Baidu ");
      names1.add("Sina ");
        
      List<String> names2 = new ArrayList<String>();
      names2.add("Google ");
      names2.add("Runoob ");
      names2.add("Taobao ");
      names2.add("Baidu ");
      names2.add("Sina ");
        
      Java8Tester tester = new Java8Tester();
      System.out.println("使用 Java 7 语法: ");
        
      tester.sortUsingJava7(names1);
      System.out.println(names1);
      System.out.println("使用 Java 8 语法: ");
        
      tester.sortUsingJava8(names2);
      System.out.println(names2);
   }
   
   // 使用 java 7 排序
   private void sortUsingJava7(List<String> names){   
      Collections.sort(names, new Comparator<String>() {
         @Override
         public int compare(String s1, String s2) {
            return s1.compareTo(s2);
         }
      });
   }
   
   // 使用 java 8 排序
   private void sortUsingJava8(List<String> names){
      Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
   }
}

执行以上脚本,输出结果为:

$ javac Java8Tester.java
$ java Java8Tester
使用 Java 7 语法: 
[Baidu , Google , Runoob , Sina , Taobao ]
使用 Java 8 语法: 
[Baidu , Google , Runoob , Sina , Taobao ]




Java 8 Stream

Java 8 新特性 Java 8 新特性


Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

以上的流程转换为 Java 代码为:

List<Integer> transactionsIds = 
widgets.stream()
             .filter(b -> b.getColor() == RED)
             .sorted((x,y) -> x.getWeight() - y.getWeight())
             .mapToInt(Widget::getWeight)
             .sum();

什么是 Stream?

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • <strong元素队列< strong="">元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

生成流

在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流。

  • parallelStream() − 为集合创建并行流。

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

forEach

Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

 


map

map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

 


filter

filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();

 


limit

limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

 


sorted

sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

 


并行(parallel)程序

parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

 

我们可以很容易的在顺序运行和并行直接切换。


Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

 

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
 
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

 


统计

另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
 
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());

Stream 完整实例

将以下代码放入 Java8Tester.java 文件中:

Java8Tester.java 文件

import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;
 
public class Java8Tester {
   public static void main(String args[]){
      System.out.println("使用 Java 7: ");
        
      // 计算空字符串
      List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
      System.out.println("列表: " +strings);
      long count = getCountEmptyStringUsingJava7(strings);
        
      System.out.println("空字符数量为: " + count);
      count = getCountLength3UsingJava7(strings);
        
      System.out.println("字符串长度为 3 的数量为: " + count);
        
      // 删除空字符串
      List<String> filtered = deleteEmptyStringsUsingJava7(strings);
      System.out.println("筛选后的列表: " + filtered);
        
      // 删除空字符串,并使用逗号把它们合并起来
      String mergedString = getMergedStringUsingJava7(strings,", ");
      System.out.println("合并字符串: " + mergedString);
      List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        
      // 获取列表元素平方数
      List<Integer> squaresList = getSquares(numbers);
      System.out.println("平方数列表: " + squaresList);
      List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
        
      System.out.println("列表: " +integers);
      System.out.println("列表中最大的数 : " + getMax(integers));
      System.out.println("列表中最小的数 : " + getMin(integers));
      System.out.println("所有数之和 : " + getSum(integers));
      System.out.println("平均数 : " + getAverage(integers));
      System.out.println("随机数: ");
        
      // 输出10个随机数
      Random random = new Random();
        
      for(int i=0; i < 10; i++){
         System.out.println(random.nextInt());
      }
        
      System.out.println("使用 Java 8: ");
      System.out.println("列表: " +strings);
        
      count = strings.stream().filter(string->string.isEmpty()).count();
      System.out.println("空字符串数量为: " + count);
        
      count = strings.stream().filter(string -> string.length() == 3).count();
      System.out.println("字符串长度为 3 的数量为: " + count);
        
      filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
      System.out.println("筛选后的列表: " + filtered);
        
      mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
      System.out.println("合并字符串: " + mergedString);
        
      squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());
      System.out.println("Squares List: " + squaresList);
      System.out.println("列表: " +integers);
        
      IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics();
        
      System.out.println("列表中最大的数 : " + stats.getMax());
      System.out.println("列表中最小的数 : " + stats.getMin());
      System.out.println("所有数之和 : " + stats.getSum());
      System.out.println("平均数 : " + stats.getAverage());
      System.out.println("随机数: ");
        
      random.ints().limit(10).sorted().forEach(System.out::println);
        
      // 并行处理
      count = strings.parallelStream().filter(string -> string.isEmpty()).count();
      System.out.println("空字符串的数量为: " + count);
   }
    
   private static int getCountEmptyStringUsingJava7(List<String> strings){
      int count = 0;
        
      for(String string: strings){
        
         if(string.isEmpty()){
            count++;
         }
      }
      return count;
   }
    
   private static int getCountLength3UsingJava7(List<String> strings){
      int count = 0;
        
      for(String string: strings){
        
         if(string.length() == 3){
            count++;
         }
      }
      return count;
   }
    
   private static List<String> deleteEmptyStringsUsingJava7(List<String> strings){
      List<String> filteredList = new ArrayList<String>();
        
      for(String string: strings){
        
         if(!string.isEmpty()){
             filteredList.add(string);
         }
      }
      return filteredList;
   }
    
   private static String getMergedStringUsingJava7(List<String> strings, String separator){
      StringBuilder stringBuilder = new StringBuilder();
        
      for(String string: strings){
        
         if(!string.isEmpty()){
            stringBuilder.append(string);
            stringBuilder.append(separator);
         }
      }
      String mergedString = stringBuilder.toString();
      return mergedString.substring(0, mergedString.length()-2);
   }
    
   private static List<Integer> getSquares(List<Integer> numbers){
      List<Integer> squaresList = new ArrayList<Integer>();
        
      for(Integer number: numbers){
         Integer square = new Integer(number.intValue() * number.intValue());
            
         if(!squaresList.contains(square)){
            squaresList.add(square);
         }
      }
      return squaresList;
   }
    
   private static int getMax(List<Integer> numbers){
      int max = numbers.get(0);
        
      for(int i=1;i < numbers.size();i++){
        
         Integer number = numbers.get(i);
            
         if(number.intValue() > max){
            max = number.intValue();
         }
      }
      return max;
   }
    
   private static int getMin(List<Integer> numbers){
      int min = numbers.get(0);
        
      for(int i=1;i < numbers.size();i++){
         Integer number = numbers.get(i);
        
         if(number.intValue() < min){
            min = number.intValue();
         }
      }
      return min;
   }
    
   private static int getSum(List numbers){
      int sum = (int)(numbers.get(0));
        
      for(int i=1;i < numbers.size();i++){
         sum += (int)numbers.get(i);
      }
      return sum;
   }
    
   private static int getAverage(List<Integer> numbers){
      return getSum(numbers) / numbers.size();
   }
}
View Code

执行以上脚本,输出结果为:

$ javac Java8Tester.java 
$ java Java8Tester
使用 Java 7: 
列表: [abc, , bc, efg, abcd, , jkl]
空字符数量为: 2
字符串长度为 3 的数量为: 3
筛选后的列表: [abc, bc, efg, abcd, jkl]
合并字符串: abc, bc, efg, abcd, jkl
平方数列表: [9, 4, 49, 25]
列表: [1, 2, 13, 4, 15, 6, 17, 8, 19]
列表中最大的数 : 19
列表中最小的数 : 1
所有数之和 : 85
平均数 : 9
随机数: 
-393170844
-963842252
447036679
-1043163142
-881079698
221586850
-1101570113
576190039
-1045184578
1647841045
使用 Java 8: 
列表: [abc, , bc, efg, abcd, , jkl]
空字符串数量为: 2
字符串长度为 3 的数量为: 3
筛选后的列表: [abc, bc, efg, abcd, jkl]
合并字符串: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
列表: [1, 2, 13, 4, 15, 6, 17, 8, 19]
列表中最大的数 : 19
列表中最小的数 : 1
所有数之和 : 85
平均数 : 9.444444444444445
随机数: 
-1743813696
-1301974944
-1299484995
-779981186
136544902
555792023
1243315896
1264920849
1472077135
1706423674
空字符串的数量为: 2

 

 

Java 8 方法引用

Java 8 新特性 Java 8 新特性


方法引用通过方法的名字来指向一个方法。

方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

方法引用使用一对冒号 :: 。

下面,我们在 Car 类中定义了 4 个方法作为例子来区分 Java 中 4 种不同方法的引用。

package com.runoob.main;
 
@FunctionalInterface
public interface Supplier<T> {
    T get();
}
 
class Car {
    //Supplier是jdk1.8的接口,这里和lamda一起使用了
    public static Car create(final Supplier<Car> supplier) {
        return supplier.get();
    }
 
    public static void collide(final Car car) {
        System.out.println("Collided " + car.toString());
    }
 
    public void follow(final Car another) {
        System.out.println("Following the " + another.toString());
    }
 
    public void repair() {
        System.out.println("Repaired " + this.toString());
    }
}
  • 构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下:

    final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );
  • 静态方法引用:它的语法是Class::static_method,实例如下:

    cars.forEach( Car::collide );
  • 特定类的任意对象的方法引用:它的语法是Class::method实例如下:

    cars.forEach( Car::repair );
  • 特定对象的方法引用:它的语法是instance::method实例如下:

    final Car police = Car.create( Car::new ); cars.forEach( police::follow );
     

    方法引用实例

    在 Java8Tester.java 文件输入以下代码:

    Java8Tester.java 文件

    import java.util.List;
    import java.util.ArrayList;
     
    public class Java8Tester {
       public static void main(String args[]){
          List names = new ArrayList();
            
          names.add("Google");
          names.add("Runoob");
          names.add("Taobao");
          names.add("Baidu");
          names.add("Sina");
            
          names.forEach(System.out::println);
       }
    }

    实例中我们将 System.out::println 方法作为静态方法来引用。

    执行以上脚本,输出结果为:

    $ javac Java8Tester.java 
    $ java Java8Tester
    Google
    Runoob
    Taobao
    Baidu
    Sina

     

    Java 8 日期时间 API

    Java 8 新特性 Java 8 新特性


    Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。

    在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

    • 非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。

    • 设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。

    • 时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

    Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

    • Local(本地) − 简化了日期时间的处理,没有时区的问题。

    • Zoned(时区) − 通过制定的时区处理日期时间。

    新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。


    本地化日期时间 API

    LocalDate/LocalTime 和 LocalDateTime 类可以在处理时区不是必须的情况。代码如下:

    Java8Tester.java 文件

    import java.time.LocalDate;
    import java.time.LocalTime;
    import java.time.LocalDateTime;
    import java.time.Month;
     
    public class Java8Tester {
       public static void main(String args[]){
          Java8Tester java8tester = new Java8Tester();
          java8tester.testLocalDateTime();
       }
        
       public void testLocalDateTime(){
        
          // 获取当前的日期时间
          LocalDateTime currentTime = LocalDateTime.now();
          System.out.println("当前时间: " + currentTime);
            
          LocalDate date1 = currentTime.toLocalDate();
          System.out.println("date1: " + date1);
            
          Month month = currentTime.getMonth();
          int day = currentTime.getDayOfMonth();
          int seconds = currentTime.getSecond();
            
          System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
            
          LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
          System.out.println("date2: " + date2);
            
          // 12 december 2014
          LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
          System.out.println("date3: " + date3);
            
          // 22 小时 15 分钟
          LocalTime date4 = LocalTime.of(22, 15);
          System.out.println("date4: " + date4);
            
          // 解析字符串
          LocalTime date5 = LocalTime.parse("20:15:30");
          System.out.println("date5: " + date5);
       }
    }
    View Code

     

    执行以上脚本,输出结果为:

    $ javac Java8Tester.java 
    $ java Java8Tester
    当前时间: 2016-04-15T16:55:48.668
    date1: 2016-04-15
    月: APRIL, 日: 15, 秒: 48
    date2: 2012-04-10T16:55:48.668
    date3: 2014-12-12
    date4: 22:15
    date5: 20:15:30

    使用时区的日期时间API

    如果我们需要考虑到时区,就可以使用时区的日期时间API:

    Java8Tester.java 文件

    import java.time.ZonedDateTime;
    import java.time.ZoneId;
     
    public class Java8Tester {
       public static void main(String args[]){
          Java8Tester java8tester = new Java8Tester();
          java8tester.testZonedDateTime();
       }
        
       public void testZonedDateTime(){
        
          // 获取当前时间日期
          ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
          System.out.println("date1: " + date1);
            
          ZoneId id = ZoneId.of("Europe/Paris");
          System.out.println("ZoneId: " + id);
            
          ZoneId currentZone = ZoneId.systemDefault();
          System.out.println("当期时区: " + currentZone);
       }
    }
    View Code

     

    执行以上脚本,输出结果为:

    $ javac Java8Tester.java 
    $ java Java8Tester
    date1: 2015-12-03T10:15:30+08:00[Asia/Shanghai]
    ZoneId: Europe/Paris
    当期时区: Asia/Shanghai








    对于中间操作和终端操作的定义,请看《JAVA8 stream接口 中间操作和终端操作》,这篇主要讲述的是stream的min,max,findFirst,findAny操作,我们先看下函数的定义

    1.  
      Optional<T> min(Comparator<? super T> comparator);
    2.  
       
    3.  
      Optional<T> max(Comparator<? super T> comparator);
    4.  
       
    5.  
      Optional<T> findFirst();
    6.  
       
    7.  
      Optional<T> findAny();

    这4个函数,都是返回的Optional对象,关于这个对象,如果有不清楚的,后期我们会做详细的介绍,现在只需要知道,这个类是对null做处理的,就可以了;

    通过函数的定义,我们其实,已经可以看到,这4个函数的作用了,min和max传入的是一个Comparator这个是一个对比接口,那么返回就是根据比较的结果,取到的集合里面,最大的值,和最小的值;

    findFirst和findAny,通过名字,就可以看到,对这个集合的流,做一系列的中间操作后,可以调用findFirst,返回集合的第一个对象,findAny返回这个集合中,取到的任何一个对象;通过这样的描述,我们也可以知道,在串行的流中,findAny和findFirst返回的,都是第一个对象;而在并行的流中,findAny返回的是最快处理完的那个线程的数据,所以说,在并行操作中,对数据没有顺序上的要求,那么findAny的效率会比findFirst要快的;下面,我们通过案例,介绍这几个的用法;

    1.  
      List<String> strs = Arrays.asList("d", "b", "a", "c", "a");
    2.  
      Optional<String> min = strs.stream().min(Comparator.comparing(Function.identity()));
    3.  
      Optional<String> max = strs.stream().max((o1, o2) -> o1.compareTo(o2));
    4.  
      System.out.println(String.format("min:%s; max:%s", min.get(), max.get()));// min:a; max:d
    5.  
       
    6.  
      Optional<String> aa = strs.stream().filter(str -> !str.equals("a")).findFirst();
    7.  
      Optional<String> bb = strs.stream().filter(str -> !str.equals("a")).findAny();
    8.  
       
    9.  
      Optional<String> aa1 = strs.parallelStream().filter(str -> !str.equals("a")).findFirst();
    10.  
      Optional<String> bb1 = strs.parallelStream().filter(str -> !str.equals("a")).findAny();
    11.  
       
    12.  
      System.out.println(aa.get() + "===" + bb.get());// d===d
    13.  
      System.out.println(aa1.get() + "===" + bb1.get());// d===b or d===c

    可以看到在min和max中,两种不同的写法,Function.identity(),表示当前对象String本身,如果集合里,是其他的实体类对象,那么可以根据实体类对象里的具体成员进行对象

    后面的findFirst和findAny也都在串行和并行中,都有解释;最后Optional的get方法,是取到这个对象,这里的是String,取出来的就是字符串

     

     

    1.lambda表达式

    《java8 Lambda表达式简介》

    《java8 lambda表达式,方法的引用以及构造器的引用》

    2.函数式接口

    《java8 函数式接口简介》

    《JAVA8 Function接口以及同类型的特化的接口》

    《JAVA8 Consumer接口》

    《JAVA8 Supplier接口》

    《JAVA8 UnaryOperator接口》

    《JAVA8 BiConsumer 接口》

    3.stream接口操作

    《java8 Stream接口简介》

    《 java8 Stream-创建流的几种方式》

    《JAVA8 stream接口 中间操作和终端操作》

    《JAVA8 Stream接口,map操作,filter操作,flatMap操作》

    《JAVA8 stream接口 distinct,sorted,peek,limit,skip》

    《java8 stream接口 终端操作 forEachOrdered和forEach》

    《java8 stream接口 终端操作 toArray操作》

    《java8 stream接口 终端操作 min,max,findFirst,findAny操作》

    《java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch》

    《java8 srteam接口终端操作reduce操作》

    《java8 stream接口 终端操作 collect操作》

    4.其他部分

    《java8 Optional静态类简介,以及用法》

     
posted @ 2020-08-13 13:58  wq9  阅读(220)  评论(0编辑  收藏  举报