JavaSE:第十六章:java8新特性(上)

简介: JavaSE:第十六章:java8新特性

##java8内容

1.Lambda表达式 ★

2.函数式接口 ★

3.方法引用 ★

4.构造器引用|数组引用 ★

5.StreamAPI ★

6.接口中可以定义默认方法和静态方法 ★

7.Optional类的引入:为了减少空指针异常【了解】

8.新日期API【了解】

9.重复注解【了解】

10.Nashone引擎的使用:在jvm上运行js【后面课程】

##Java8引进

1995年推出jdk1.0

04年推出 jdk5 ,改革非常大

06年推出 jdk6 ,企业中使用的最长久版本

--------被Oralce公司收购-----------

11年 推出 jdk7

14年 推出 jdk8 LTS版本:受商业公司支持的长期版本

17年 9月份推出 jdk9, “六个月版本升级计划” 小版本

18年 3月份 推出jdk10 小版本

18年 9月份 推出jdk11 LTS版本:

##Lambda表达式

###理解

理解成一段可以传递的代码,作为函数式接口的实例出现

###应用场景

示例1:

接口 a = Lambda表达式;

示例2:【居多】

method(Lambda表达式);

public void method(接口 a){

}

###好处

1、语句更加简洁

2、更加紧凑,使java语言的表达能力得到了提升!

###语法 ★

(参数类型 参数名,参数类型 参数名)->{方法体的实现/Lambda体}

示例:

(String o1, String o2)->{return o1.compareTo(o2);}

特点:

①左侧参数列表中的参数类型可以省略!

②如果左侧参数列表中,只有一个参数,则小括号也可以省略

③右侧的Lambda体中如果仅有一句话,则大括号可以省略

④右侧的Lambda体中仅有的一句话为return语句,则return要求省略

##函数式接口

理解:

只有一个抽象方法的接口,称为函数式接口

Consumer消费型接口

Supplier供给型接口

Function<T,R>函数型接口

Predicate 断定型接口

##方法引用

###理解

* 方法引用实质上就是Lambda表达式的简化,同样可以作为函数式接口的实例出现

* 能用方法引用 的肯定能用Lambda表达式

* 能用Lambda表达式的不一定能用方法应用,除非满足以下要求:

###要求:

①Lambda体中仅仅只有一句话

②仅有的一句话为 方法调用!

③调用方法的参数列表和Lambda体实现的抽象方法的参数列表一致!

调用方法的返回类型和Lambda体实现的抽象方法的返回类型一致!

特例:类名::普通方法

调用方法的调用者正好是 抽象方法的第一个参数,并且其他参数一致

调用方法的返回类型和抽象方法的返回类型一致!

###语法:

类名或对象::方法名

###情况:

* 1、对象::普通方法

* 2、类名::静态方法

* 3、类名::普通方法

##关于方法引用、数组引用、构造器引用的总结

1.能使用方法引用|数组引用|构造器引用的地方,肯定能用Lambda表达式!

2.能用Lambda表达式的地方,不一定能用方法引用|数组引用|构造器引用,必须满足以下条件

3.能使用Lambda表达式的地方,肯定能用匿名内部类

能用匿名内部类的,不一定能用Lambda表达式,必须满足:

实现的接口为 函数式接口(里面只有一个抽象方法的接口)!

方法引用:

①Lambda体只有一句话

②仅有的一句话为调用方法

③方法的参数列表、返回类型正好与抽象方法的参数列表、返回类型一致!

特殊:如果是类名::普通方法,则要求方法的调用者为抽象的方法的第一个参数,其他一致

 此类用于演示方法引用
 *  举例:
 *     匿名内部类:
 *    UnaryOperator<Double> up = new UnaryOperator<Double>(){
 *      public Double apply(Double t){
 *            return Math.sqrt(t);
 *          }
 *     };
 *     Lambda:
 *     UnaryOperator<Double> up =d->Math.sqrt(d);
 *     方法引用:
     UnaryOperator<Double> up = Math::sqrt;
 */
public class TestMethodRef {
  //1、对象::普通方法
  @Test 
  public void test1_1() {
    //匿名内部类
//    Runnable r = new Runnable() {
//      @Override
//      public void run() {
//        System.out.println();
//      }
//    };
    //方法引用
    Runnable r2 = System.out::println;
    r2.run();
  }
  //对象::普通方法
  @Test 
  public void test1_2() {
    //匿名内部类
//    Consumer<String> con = new Consumer<String>() {
//      @Override
//      public void accept(String t) {
//        System.out.println(t);
//        
//      }
//    };
    //方法引用
    Consumer<String> con2 = System.out::println;
    con2.accept("赵丽颖和冯绍峰已经结婚了");
  }
  //2、类名::静态方法
  @Test 
  public void test2() {
    //匿名内部类
    Comparator<Double> com = new Comparator<Double>() {
      @Override
      public int compare(Double o1, Double o2) {
        return Double.compare(o1, o2);
      }
    };
    //Lambda
    Comparator<Double> com1 = (o1,o2)->Double.compare(o1, o2);
    //方法引用
    Comparator<Double> com2 =Double::compare;
  }
  //3、类名::普通方法
  @Test 
  public void test3() {
    //匿名内部类
//    Function<Employee,String> fun = new Function<Employee,String>(){
//      @Override
//      public String apply(Employee t) {
//        return t.getName();
//      }
//    };
    //方法引用
    Function<Employee,String> fun2 = Employee::getName;
    System.out.println(fun2.apply(new Employee("张无忌", 12, 1000, '男')));
  }
  //3、类名::普通方法
  @Test 
  public void test3_2() {
    //匿名内部类
//    BiFunction<String, String, Boolean>  bf = new BiFunction<String, String, Boolean>() {
//      @Override
//      public Boolean apply(String t, String u) {
//        return t.equals(u);
//      }
//    };
    //方法引用
    BiFunction<String, String, Boolean>  bf2 = String::equals;
    System.out.println(bf2.apply("hello", "Hello"));
  }
}

构造器引用

理解:构造器引用本质上就是Lambda表达式,只是语句更加简洁。作为函数式接口的实例,一般作为参数传递给方法!

能用构造器引用的地方,肯定能用Lambda表达式

但能用Lambda表达式的地方,不一定能用构造器引用

要求:

①Lambda体中仅仅只有一句话

②仅有的一句话为调用构造器 new ClassName(实参列表);

③抽象方法的参数列表和构造器的参数列表完全一致

抽象方法的返回类型为构造器所属的类型。

语法:

类名::new

 此类用于演示构造器引用
public class TestConstructorRef {
  //案例1:返回new String();
  @Test 
  public void test1() {
    //匿名内部类
//    Supplier<String> sup = new Supplier<String>() {
//      @Override
//      public String get() {
//        return new String();
//      }
//    };
    //构造器引用
    Supplier<String> sup2 = String::new;
    int length = sup2.get().length();
    System.out.println(length);
  }
  //案例2:返回new StringBuffer(int capacity);
    @Test 
    public void test2() {
      Function<Integer,StringBuffer> fun = new Function<Integer,StringBuffer>(){
        @Override
        public StringBuffer apply(Integer t) {
          return new StringBuffer(t);
        }
      };
      Function<Integer,StringBuffer> fun2 = StringBuffer::new;
    }
    //案例3:返回new Employee("段誉", 22, 10000, '男')
    @Test 
    public void test3() {
      A<String,Integer,Double,Character,Employee> a1 = (s,i,d,c)->new Employee(s,i,d,c);
      A<String,Integer,Double,Character,Employee> a = Employee::new;
    }
}
interface A<T,R,U,M,N>{
  N test(T t,R r,U u,M m);
}

数组引用

理解:数组引用本质上就是Lambda表达式,只是语句更加简洁。作为函数式接口的实例,一般作为参数传递给方法!

能用数组引用的地方,肯定能用Lambda表达式

但能用Lambda表达式的地方,不一定能用数组引用

要求:

①Lambda体仅仅有一句话

②仅有的一句话为返回一个新数组 new 数组类型[长度];

③抽象方法的参数只有一个,就是数组的长度;抽象方法的返回为创建的新数组类型

语法:

数组类型[]::new

此类用于演示数组引用
public class TestArrayRef {
  //案例1:返回一个String[] s = new String[5]
  @Test 
  public void test1() {
    //匿名内部类
//    Function<Integer,String[]>  fun = new Function<Integer,String[]>(){
//      @Override
//      public String[] apply(Integer t) {
//        return new String[t];
//      }
//    };
    //数组引用
    Function<Integer,String[]>  fun2 = String[]::new;
    String[] arr = fun2.apply(5);
    for (String string : arr) {
      System.out.println(string);
    }
  }
  //案例2:返回一个Employee[]
  @Test 
  public void test2() {
    Function<Integer,Employee[]> fun = Employee[]::new;
    Employee[] apply = fun.apply(3);
    for (Employee employee : apply) {
      System.out.println(employee);
    }
  }
}

综述:匿名内部类》Lambda表达式》方法引用|数组引用|构造器引用

##StreamAPI

###好处

1、更高效

2、易于使用,提供了丰富强大的方法。

###使用步骤

1.开始操作(√)

说明:创建Stream对象,指向一个具体的数据源(集合、数组、一系列值、无线流)

2.中间操作(可选 0——n)

说明:对数据源数据的计算、处理

3.终止操作(√)

说明:想要一个结果(打印、计数、去最值等)

###使用特点

1、Stream讲究的是“计算”,可以处理数据,但不能更新源数据
2、Stream 属于“惰性操作”,必须等待终止操作执行后,前面的中间操作或开始操作才会处理
3、Stream只能消费一次,一旦消费,就不能再次使用,除非重新创建Stream对象
4、Stream的中间操作可以有0个或多个,每个操作都会返回一个新的Stream
5、Stream相当于一个 更强大的Iterator,可以处理更加复杂的数据,并且实现并行化,效率更高!

相关文章
|
1月前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
60 2
|
1月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
39 3
|
1月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
33 2
|
1月前
|
存储 算法 Java
Java Set因其“无重复”特性在集合框架中独树一帜
【10月更文挑战第14天】Java Set因其“无重复”特性在集合框架中独树一帜。本文深入解析Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定的数据结构(哈希表、红黑树)确保元素唯一性,并提供最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的`hashCode()`与`equals()`方法。
31 3
|
16天前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
28 4
|
1月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
58 3
|
1月前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
24 2
|
1月前
|
Java 开发者
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素。通过哈希表和红黑树两种模式,Set能够高效地识别并拒绝重复元素的入侵,确保集合的纯净。无论是HashSet还是TreeSet,都能在不同的场景下发挥出色的表现,成为开发者手中的利器。
27 2
|
1月前
|
Java
Java Set以其“不重复”的特性,为我们提供了一个高效、简洁的处理唯一性约束数据的方式。
【10月更文挑战第16天】在Java编程中,Set接口确保集合中没有重复元素,每个元素都是独一无二的。HashSet基于哈希表实现,提供高效的添加、删除和查找操作;TreeSet则基于红黑树实现,不仅去重还能自动排序。通过这两个实现类,我们可以轻松处理需要唯一性约束的数据,提升代码质量和效率。
38 2
|
1月前
|
存储 Java 数据处理
在Java集合框架中,Set接口以其独特的“不重复”特性脱颖而出
【10月更文挑战第14天】在Java集合框架中,Set接口以其独特的“不重复”特性脱颖而出。本文通过两个案例展示了Set的实用性和高效性:快速去重和高效查找。通过将列表转换为HashSet,可以轻松实现去重;而Set的contains方法则提供了快速的元素查找功能。这些特性使Set成为处理大量数据时的利器。
18 4
下一篇
无影云桌面