java8新特性

Posted 野生java研究僧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8新特性相关的知识,希望对你有一定的参考价值。

java8新特性:

  1. 速度更快
  2. 代码更少(新增语法:Lambda 表达式)
  3. 新增 Stream API
  4. 便于执行
  5. 最大化减少空指针异常:Option
  6. Nashorn引擎,运行在jvm中运行 java script 代码,jdk6就可以,但是jdk8做了更好的优化

例如:在java的bin目录下使用 jjs命令编译以下js代码:jjs fileName.js

print(add(5,6))
function add( a,b) {
     var sum=a+b;
    return a+b;
}

1.Lambda表达式

Lambda 是一个匿名函数,可以把 Lambda理解为是一段可以传递的代码(将代码像数据一样进行传递),使用它可以让我们的变的更加简洁,让java语言的表达能力得到了提升,让我们写的代码更加简短,优雅。

1.Lambda表达式和方法引用的案例

import org.junit.jupiter.api.Test;

import java.util.Comparator;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:02
 * @Version:1.0
 * @Description: Lambda表达式和方法引用的入门案例
 */
public class LambadaTest {

    // 使用原来的方式:new一个接口,实现匿名对象
    @Test
    void test1(){

       Runnable runnable= new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world1");
            }
        };
        // 使用对象调用普通方法 run(),并不是多线程的方式进行启动
       runnable.run();
    }

    // 使用Lambda的方式
    @Test
    void test2(){
        Runnable runnable=()->System.out.println("hello world2");
        runnable.run();
    }

    // 原生方式
    @Test
    void test3(){
        Comparator comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // o1>o2: result>0   o1<o2:result<0  o1=o2:result=0
                return Integer.compare(o1,o2);
            }
        };
        int result = comparator.compare(20, 10);
        System.out.println("result="+result);
    }
   // 使用Lambda表达式
    @Test
    void test4(){
        Comparator<Integer> comparator=(o1,o2)->Integer.compare(o1,o2);
        int result = comparator.compare(20, 20);
        System.out.println("result="+result);
    }
    // 使用方法引用
    @Test
    void test5(){
        Comparator<Integer> comparator=Integer::compare;
        int result = comparator.compare(20, 20);
        System.out.println("result="+result);
    }

}

2.Lmabda表达式的6种形式

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:25
 * @Version:1.0
 * @Description: Lambda表达式
 *1.举例: (o1,o2)->Integer.compare(o1,o2);
 *2.格式:
 *      ->   : lambda操作符 或 箭头操作符
 *      左边 : Lambda形参列表 (抽象接口中的方法参数)
 *      右边 : Lambda体(重写抽象方法的方法体)
 *3.Lambda表达式的使用:分为6种情况
 *  1.无参,无返回值
 *  2.有一个参数,但是无返回值
 *  3.数据类型可以省略,因为编译器推断得出,称为 “类型推断”。
 *  4.Lambda表达式:若只需要一个参数时,参数的小括号可以省略
 *  5.Lambda表达式:需要两个或以上的参数,执行多条语句,并且可以有返回值
 *  6.Lambda表达式:当Lambda表达式至有一条语句时,return与大括号有 ,都可以省略
 *
 *4.Lambda表达式的本质:作为接口的实例(依赖于函数式接口:@FunctionalInterface)
 *
 */
public class LambdaDemo1 {

    // 1.Lambda表达式:无参无返回值
    @Test
    void test1(){
      Runnable runnable=()->System.out.println("hello world");
      runnable.run();
    }

    //2.Lambda表达式:有一个参数,但是没有返回值
    @Test
    void test2(){
        // 原生方式
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("result="+s);
            }
        };
        consumer.accept("admin");


        System.out.println("-----------------------------");
        // Lambda表达式的方式:
        Consumer<String> consumer2=(String s)->{
            System.out.println("result="+s);
        };
        consumer2.accept("lambda");
    }
    // 3.Lambda表达式:数据类型可以省略,编译器推断得出 称为 “类型推断”
    @Test
    void test3(){
        Consumer<String> consumer=(s)->{
            System.out.println("result="+s);
        };
        consumer.accept("hello");

        ArrayList<String> list = new ArrayList<>();//类型推断
        int[] arr={1,2,3};// 类型推断
    }
    //4.Lambda表达式:若只需要一个参数时,参数的小括号可以省略
    @Test
    void test4(){
        Consumer<String> consumer= arg->{
            System.out.println("result="+arg);
        };
        consumer.accept("hello");
    }
   //5.Lambda表达式:需要两个或以上的参数,执行多条语句,并且可以有返回值
   @Test
    void test5(){
       Comparator<Integer> comparator=(o1,o2)->{
           int result = Integer.compare(o1, o2);
           return result;
       };
       int result = comparator.compare(20, 15);
       System.out.println("result="+result);
   }

   //6.Lambda表达式:当Lambda表达式只有一条语句时,return与大括号都可以省略
    @Test
    void test6(){
        Comparator<Integer> comparator = (o1,o2)->Integer.compare(o1,o2);
        int result = comparator.compare(20, 52);
        System.out.println("result="+result);

    }
}

3.Lambda表达式详细实例

1.无参数,无返回值

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:无参数,无返回值
 */
@FunctionalInterface
public interface LambdaInterface{
   
    void show();

}
class MyTest{
    public static void main(String[] args) {
        //1.无参无返回值写法1:至有一条语句
        LambdaInterface l1=()->System.out.println("hello world");
        l1.show();

        System.out.println("-------------------------");

        //1.无参无返回值写法1:需要执行多条语句
        LambdaInterface l2=()->{
            System.out.println("hello world1");
            System.out.println("hello world2");
        };
        l2.show();
    }
}

2.有一个参数但无返回值

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:有一个参数但无返回值
 */
@FunctionalInterface
public interface LambdaInterface{

    void select(String id);


}
class MyTest{
    public static void main(String[] args) {
        // 只有一条语句
       LambdaInterface l1=(String id)->System.out.println("id="+id);

       // 如果是多条语句:使用{}包起来
        LambdaInterface l2=(String id)->{
            if (id.equals("123")){
                System.out.println("查询成功");
            }else {
                System.out.println("查询失败");
            }
        };

        l1.select("123");
        l2.select("234");
    }
}

3.数据类型可以省略,根据编译器根据编译器推断得出,称为:类型推断



/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:数据类型可以省略,根据编译器推断得出,称为 “类型推断”
 */
@FunctionalInterface
public interface LambdaInterface{

    void select(String id);


}
class MyTest{
    public static void main(String[] args) {
        // 只有一条语句(在上一个基础的例子上去掉了数据类型)
       LambdaInterface l1=( id)->System.out.println("id="+id);

       // 如果是多条语句:使用{}包起来(在上一个基础的例子上去掉了数据类型)
        LambdaInterface l2=( id)->{
            if (id.equals("123")){
                System.out.println("查询成功");
            }else {
                System.out.println("查询失败");
            }
        };

        l1.select("123");
        l2.select("234");
    }
}

4.若只需要一个参数时,-> 左边小括号可省略(多个参数则不可省)

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:若只需要一个参数时,-> 左边小括号可省略(多个参数则不可省)
 */
@FunctionalInterface
public interface LambdaInterface{

    void select(String id);


}
class MyTest{
    public static void main(String[] args) {
        // 只有一条语句(在上一个基础的例子上去掉了小括号)
       LambdaInterface l1 = id ->System.out.println("id="+id);

       // 如果是多条语句:使用{}包起来((在上一个基础的例子上去掉了小括号)
        LambdaInterface l2 = id->{
            if (id.equals("123")){
                System.out.println("查询成功");
            }else {
                System.out.println("查询失败");
            }
        };

        l1.select("123");
        l2.select("234");
    }
}

5.需要多个参数,有返回值,并且需要执行多行代码

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:需要多个参数,并且有返回值,需要return返回值
 */
@FunctionalInterface
public interface LambdaInterface{

    String login(String username,String password);


}
class MyTest{
    public static void main(String[] args) {

       LambdaInterface l = (username,password)->{
           if ("admin".equals(username)&&"123".equals(password))return " login success";
           return "login fail";
       };
        String result = l.login("admin", "123");
        System.out.println("result="+result);
    }
}


6.当Lambda表达式只有一条语句时,return与大括号都可以省略

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: compass
 * @Date: 2021-10-21-20:29
 * @Version:1.0
 * @Description:  Lambda表达式:有返回值,只需要只需要一条语句时,return和{}都可以省略
 */
@FunctionalInterface
public interface LambdaInterface{

    String login(String username,String password);


}
class MyTest{
    public static void main(String[] args) {
LambdaInterface l = (username,password)->username.equals("admin")&&password.equals("123")?" success":" fail";
       String result = l.login("admin", "123");
       System.out.println("result="+result);
    }
}

2.函数式接口

1.函数式接口描述

1.只包含一个抽象方法的接口称之为:函数式接口

2.你可以使用Lambda表达式来创建该接口的实例对象,(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在模板接口的方法上进行声明)

3.我们可以在接口上使用 @FunctionalInterface注解,这样可以检测该接口是否是一个函数式接口,加上了该注解,就意味着该接口只能有一个抽象方法,如果有多个会抛出编译时异常,即使不加该注解,只有一个接口中只定义了一个抽象方法,该接口依旧是函数式接口,@FunctionalInterface 注解只是帮我们在编译时检测该接口是否满足函数式接口的要求。

4.在 java.util.function下定义了 java8 丰富的函数式接口,Lambda的本质就是函数式接口的一个实例对象

2.java内置四大函数式接口

四大函数式接口指的是Consumer、Function、Predicate、Supplier 位于java.util.function包下

第一种:Consumer:消费型接口(传递一个对象,进行消费,不返回非任何结果)void accept(T t);

第二种:Supplier:供给型接口 (不传递任何参数,给你返回一个对象) T get();

第三种:Function<T,R>:函数型接口 ,(对类型为T的对象进行操作,返回操作的结果为 R) R apply(T t);

第四种:Predicate:断言型接口(传递一个对象,进行判断,返回判断的结果) boolean test(T t)

实例:

public class FunctionInterface {

    @Test
    void test1(){
        List<String> list = Arrays.asList("北京", "南京", "东京", "重庆", "四川", "深圳");
        List<String> result = filterString(list, arg -> arg.contains("京"));
        System.out.println(result);


    }

    /**
     * 根据给定的规则对List集合中的字符串进行过滤
     * @param list list集合
     * @param predicate 过滤规则
     * @return 过滤后的List集合
     */
    public static List<String> filterString(List<String> list , Predicate<String> predicate){
        List<String> filter = new ArrayList<>();
        for (String value:list){
            // 如果满足规则就加入到一个新的集合中
            if (predicate.test(value)) filter.add(value);
        }
        return filter;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1Izktrm-1635059552943)(C:\\Users\\14823\\AppData\\Roaming\\Typora\\typora-user-images\\image-20211021233411179.png)]

3.方法引用与构造器

1.方法引用

1.当要传递的Lambda表体操作,已经有具体实现方法的时候,可以直接使用方法引用

2.方法引用可以看做是Lambda表达式深层次的表达,方法引用就是Lambda表达式,也就是函数式接口的实例,通过方法的名字来指向一个方法。

3.要求:实现抽象接口的方法的参数列表和返回值,必须与方法引用的方法参数列表和返回值保持一致。

4.使用格式:使用操作符 :: 将类或者方法名分开。