java8-新特性(代码片段)

钢铁-程序猿 钢铁-程序猿     2023-03-23     564

关键词:

文章目录

Java8新特性

  • 1、Lambda表达式
  • 2、函数式接口
  • 3、方法引用与构造器引用
  • 4、Stream API
  • 5、接口中的默认方法与静态方法
  • 6、新时间日期API
  • 7、其它新特性

一、Lambda表达式

Lambda表达式可以理解为作为实现类对象传入函数

Lambda表达式是一个匿名函数,我们可以把Lambda表达式理解为一段可以传递的代码(将代码像数据一样进行传递),可以写出更加简洁、更加灵活的代码。作为一种更紧凑的代码风格,使Java语言表达能力得到了提升。

匿名内部类

abstract class Person 
    public abstract void eat();

//匿名内部类
public class Demo 
    public static void main(String[] args) 
    	//实现类并没具体名称
        Person p = new Person() 
            public void eat() 
                System.out.println("eat something");
            
        ;
        p.eat();
    

Lambda表达式

import org.junit.Test;

import java.util.Comparator;
import java.util.TreeSet;

public class Lambda 
    //原来的匿名内部类
    @Test
    public void test1()
    
        Comparator<Integer> com = new Comparator<Integer>() 
            @Override
            public int compare(Integer o1, Integer o2) 
                return Integer.compare(o1,o2);
            
        ;
        TreeSet<Integer> ts = new TreeSet<>(com);
    

    //Lambda表达式
    //使用Lambda使用的代码量少了
    @Test
    public void test2()
    
        Comparator<Integer> com = (x,y)->Integer.compare(x,y);
        TreeSet<Integer> ts = new TreeSet<>(com);
    

 

例子

import org.junit.Test;

import java.util.*;

public class Lambda 
    List<Employee> employees = Arrays.asList(
        new Employee("张三",18,9999.99),
        new Employee("李四",38,5555.55),
        new Employee("王五",50,6666.66),
        new Employee("赵六",16,3333.33),
        new Employee("田七",8,7777.77)
    );

    //需求:获取当前公司中员工年龄大于35的员工信息
    public List<Employee> filterEmployees(List<Employee> list)
    
        List<Employee> emps = new ArrayList<>();
        for (Employee emp:list)
        
            if(emp.getAge()>=35)
            
                emps.add(emp);
            
        
        return emps;
    

    //需求:获取当前公司员工工资大于5000的员工信息
    public List<Employee> filterEmployees2(List<Employee> list)
    
        List<Employee> emps = new ArrayList<>();
        for (Employee emp:list)
        
            //唯一和上面一个函数不同的一行,需求变动可能对代码的影响很小,但是要重新写一个函数
            //比较复杂
            if(emp.getSalary()>=5000)
            
                emps.add(emp);
            
        
        return emps;
    


优化一:使用策略设计模式

import org.junit.Test;

import java.util.*;

public class Lambda 
    //优化方式一:

    public interface MyPredicate<Employee> 
        public boolean test(Employee employee);
    

    class FilterEmployeeByAge implements MyPredicate<Employee>
    

        @Override
        public boolean test(Employee employee) 
            return employee.getAge()>=35;
        
    

    //将Java类按照MyPredicate的方式进行过滤
    //方法只要写这一个,传入不同的类,即可按照不同的实现方式进行过滤
    public List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mp)
    
        List<Employee> emps = new ArrayList<>();
        for (Employee employee:list)
        
            if (mp.test(employee))
            
                emps.add(employee);
            
        
        return emps;
    



优化方式二:匿名内部类

import org.junit.Test;

import java.util.*;

public class Lambda 
    //优化方式二:匿名内部类
    @Test
    public void test5()
    
        List<Employee> list = filterEmployee(employees, new MyPredicate<Employee>() 
            @Override
            public boolean test(Employee employee) 
                return employee.getSalary()<=5000;
            
        );

        for (Employee employee:list)
        
            System.out.println(employee);
        
    



优化方式三:Lambda表达式

public class Lambda 
    //优化方式三:Lambda表达式
    @Test
    public void test6()
    
    	List<Employee> list = filterEmployee(employees,(e)->e.getSalary()<=5000);
    

优化方式四:Stream API

public class Lambda 
    //优化方式四:
    @Test
    public void test7()
    
    	//限制输出前两个
    	employees.stream()
    		     .filter((e)->e.getSalary()>=5000)
    		     .limit(2)
    		     .forEach(System.out::println);
    	//将所有人的名字提取出
    	employees.stream()
    		     .map(Employee::getName)
    		     .forEach(System.out::println);
    

Lambda表达式的基本语法

Java8引入了一个新的操作符“->”,该操作符称为箭头操作符或Lambda操作符
箭头操作符将Lambda表达式拆分成两个部分:

  • 1、左侧:Lambda表达式的参数列表
  • 2、右侧:Lambda表达式中所需要执行的功能,即Lambda体

Lambda表达式需要一个函数式接口的支持,所谓的函数式接口指的是接口中只有一个抽象方法的接口

语法格式一

无参数,无返回值

()->System.out.println(“Hello Lambda!”);

import org.junit.Test;

public class TestLambda1 

	//无参数并且无返回值
    @Test
    public void test1()
    
        //匿名内部类
        Runnable r = new Runnable() 
            @Override
            public void run() 
                System.out.println("hello world!");
            
        ;
        r.run();
        System.out.println("-------------");

        //Lambda表达式
        Runnable r1 = ()-> System.out.println("Hello Lambda");
        r1.run();
    

语法格式二

语法格式二:有一个参数,但是没有返回值。
(x)-> System.out.println(x);
若只有一个参数,小括号可以省略不写,
x-> System.out.println(x);

public class TestLambda1 

	@Test
    public void test2()
    
        Consumer<String> con = (x)-> System.out.println(x);
        //小括号可以不写
        //Consumer<String> con = x-> System.out.println(x);
        con.accept("威武 ");
    

语法格式三

有两个及以上的参数,有返回值,并且Lambda体中有多条语句

@Test
public void test3()

	Comparator<Integer> com = (x,y)->
	            System.out.println("函数式接口");
	            return Integer.compare(x,y);
	        ;

语法格式四

若Lambda体中只有一条语句,return和大括号都可以省略不写

@Test
public void test4()

    Comparator<Integer> com = (x,y)-> Integer.compare(x,y);

语法格式五

Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以通过上下文推断出数据类型,这个过程称之为“类型推断”。

  • (x,y)-> Integer.compare(x,y);

这个和数组初始化类似,可以通过左边的定义的数组的类型推断出大括号里所给的是字符串类型的数据。

  • String[] strs = “aaa”,“bbb”,“ccc”;
    但是如果拆分开来写就不可以
  • String[] strs;
  • strs = “aaa”,“bbb”,“ccc”;
//可以通过函数参数类型,推断出参数类型,则左侧类型可写可不写。
(Integer x,Integer y)->Integer.compare(x,y);

总结

  • 左右遇一括号省(左边只有一个参数则括号可以省略,右边只有一条语句,那么大括号省略)
  • 左侧推断类型省(可以通过函数参数类型,推断出参数类型,则左侧类型可写可不写。)
  • Lambda表达式需要函数式接口的支持,接口中只有一个抽象的方法的接口称为函数式接口,函数式接口可以使用一个注解即@FunctionalInterface修饰一下。

Lambda表达式的使用例子

例子1:使用Lambda表达式对一个数进行操作

import org.junit.Test;
@FunctionalInterface
public interface MyFun 
    public Integer getValue(Integer num);


public class TestLambda2 
    //需求:对一个数进行运算
    @Test
    public void test()
    
    	//具体什么操作通过Lambda表达式实现
        Integer num = operation(100, x -> x * x);
        System.out.println(num);
    
    public Integer operation(Integer num,MyFun mf)
    
        return mf.getValue(num);
    




例子2:使用Lambda进行定制排序

调用Collection.sort()方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda表达式作为参数传递。

import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class TestLambda3 

    List<Employee> emps = Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",59,6666.66),
            new Employee("王五",28,3333.33),
            new Employee("赵六",8,7777.77),
            new Employee("田七",38,5555.55)
    );

    @Test
    public void test1()
    
        Collections.sort(emps,(e1,e2)->
            if(e1.getAge() == e2.getAge())
            
                return e1.getName().compareTo(e2.getName());
            
            else
            
                return Integer.compare(e1.getAge(),e2.getAge());
            
        );

        for (Employee emp:emps)
        
            System.out.println(emp);
        
    

例子三

  • 1、声明函数式接口,接口中声明抽象方法,public String getValue(String str);
  • 2、声明类TestLambda,类中编写方法使用接口作为参数,将一个字符串转化为大写,并作为方法的返回值。
  • 3、再将一个字符串的第2个和第4个索引位置进行截取子串。
import org.junit.Test;
import java.util.Locale;

@FunctionalInterface
interface MyFunction

    public String getValue(String str);

public class TestLambda4 
    public String strHandler(String str,MyFunction mf)
    
        return mf.getValue(str);
    

    @Test
    public void test()
    
        String trimStr = strHandler("\\t\\t\\t abcdef",str-> str.trim());
        String upper = strHandler(trimStr,str-> str.toUpperCase());
        String newStr = strHandler(upper,str-> str.substring(2,5));
        System.out.println(newStr);
    

例子四

  • 1、声明一个带两个泛型的函数式接口,泛型类型为<T,R>,T为参数,R为返回值
  • 2、接口中声明对应抽象方法。
  • 3、在TestLambda类中声明方法,使用接口作为参数,计算两个long参数的和。
  • 4、在计算两个long型参数的乘积。
public class TestLambda

	@Test
    public void test3()
    
        op(100L,200L,(x,y)->x+y);
        op(100L,200L,(x,y)->x*y);
    
    @FunctionalInterface
    interface MyFunction2
    
        public long getvalue(long l1,long l2);
    
    public void op(long l1,long l2,MyFunction2 mf)
    
        System.out.println(mf.getvalue(l1,l2));
    

java内置四大核心函数式接口(Consumer、Supplier、Function、Predicate)

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Java8内置的四大函数式接口
 * Consumer<T>:消费型接口
 *      void accept(T t);
 *
 * Supplier<T>:供给型接口
 *      T get();
 *
 * Function<T,R>:函数型接口
 *      R apply(T t);
 *
 * Predicate<T>:断言型接口
 *      boolean test(T t);
 */
public class TestLambda5 
    //Consumer<T> 消费型接口:
    @Test
    public void test1()
    
        happy(1000,m-> System.out.println("消费"+m+"元"));
    
    public void happy(double money, Consumer<Double> con)java8十大新特性详解(代码片段)

前言: Java 8已经发布很久了,很多报道表明Java 8是一次重大的版本升级。在JavaCodeGeeks上已经有很多介绍Java8新特性的文章,例如PlayingwithJava8–LambdasandConcurrency、Java8DateTimeAPITutorial:LocalDateTime和AbstractClassVersusInterfacein 查看详情

重学java8新特性|第2讲——java8新特性简介(代码片段)

请再看我一眼写在前面你能从这套课程中学到什么呢?Java8有哪些优点?速度更快更新了底层的数据结构Java8对于HashMap所做的改动Java8对于ConcurrentHashMap所做的改动更新了底层的内存结构代码更少(增加了新的语法࿰... 查看详情

重学java8新特性|第2讲——java8新特性简介(代码片段)

请再看我一眼写在前面你能从这套课程中学到什么呢?Java8有哪些优点?速度更快更新了底层的数据结构Java8对于HashMap所做的改动Java8对于ConcurrentHashMap所做的改动更新了底层的内存结构代码更少(增加了新的语法࿰... 查看详情

java8新特性(代码片段)

...的JavaScript引擎,新的日期API,新的StreamAPI等。新特性Java8新增了非常多的特性,我们主要讨论以下几个:Lambda: 查看详情

拥抱变化,面向java17,java8-18全系列特性详解(代码片段)

文章目录:Java8新特性Java9新特性Java10新特性Java11新特性Java12新特性Java13新特性Java14新特性Java15新特性Java16新特性Java17新特性Java18新特性💡文章较长,建议点赞、收藏、评论后慢慢看,合理利用“只看目录功能”... 查看详情

拥抱变化,面向java17,java8-18全系列特性详解(代码片段)

文章目录:Java8新特性Java9新特性Java10新特性Java11新特性Java12新特性Java13新特性Java14新特性Java15新特性Java16新特性Java17新特性Java18新特性💡文章较长,建议点赞、收藏、评论后慢慢看,合理利用“只看目录功能”... 查看详情

java8新特性(代码片段)

java8新特性1.Lambda表达式1.Lambda表达式和方法引用的案例2.Lmabda表达式的6种形式3.Lambda表达式详细实例2.函数式接口1.函数式接口描述2.java内置四大函数式接口3.方法引用与构造器1.方法引用2.构造器引用4.StreamAPI1.StreamAPI说明2.stream实... 查看详情

java8新特性。(代码片段)

常用函数接口:函数式接口:函数式接口在Java中是指:有且仅有一个抽象方法的接口(可以含其他方法)。而Java中的函数式编程的体现就是Lambda。@FunctionalInterface注解:检测接口是否是函数式接口。函数式接口的使用:一般可... 查看详情

重学java8新特性|第1讲——我们为什么要学习java8新特性?(代码片段)

...又重新来更文了,只不过这次我更新的是有关Java8新特性的文章,至于原因是什么,下面我会告诉大家。原因一大家应该知道我正在更新「SpringBoot2从入门到入坟」专栏吧!这里,我就得向大家吐吐苦水了,... 查看详情

java8新特性-----新时间与日期api(代码片段)

新时间与日期API新的时间和日期APIInstant:时间戳Duration计算时间间隔,Period计算日期间隔时间校正器时间和日期格式化---DateTimeFormatter新的时间和日期API//只获取当前系统的日期LocalDatenow=LocalDate.now();System.out.println("当前... 查看详情

java8新特性optional类(代码片段)

目录1Java8Optional类简介1.1类声明1.2类方法2Optional实例1Java8Optional类简介Optional类主要解决的问题是臭名昭著的空指针异常(NullPointerException),提供了一些的方法代替过去的if-else处理逻辑,并与Stream流结合提供一致性的函数式... 查看详情

第六周java8新特性(代码片段)

...:(parameters)->expression或(parameters)->statements;还有如下特性:可选类型声明:不需要声明参数类型,由编译器统一识别参数值可选参数的圆括号:一个参数时可以不要写括号,多个参数需要写 查看详情

java8新特性(代码片段)

尚硅谷视频优点:速度更快代码更少(增加了新的语法Lambda表达式)强大的StreamAPI便于并行最大化减少空指针异常Optional其中最为核心的为Lambda表达式与StreamAPI1、Lambda表达式1.1、为什么使用Lambda表达式Lambda是一个匿名... 查看详情

java8新特性----stream(代码片段)

Stream流WhatisStream?注意:Stream操作三部曲使用演示:中间操作筛选与切片内部迭代:迭代操作由StreamAPI完成终止操作:一次性执行全部内容,即惰性求值外部迭代limit===>短路skip===>跳过前n个元素distinct进行元素... 查看详情

java8新特性之lambda(代码片段)

...译自@shekhargulati的java8-the-missing-tutorialJava8中最重要的特性之一就是引入了lambda表达式。这能够使你的代码更加简练,并允许你将行为传递到各处。一段时间以来,Java因为自身的冗长和缺少函数式编程的能力而受到批评... 查看详情

java8新特性3streamapi(代码片段)

一Stream1.1stream的概述stream是java8的新特性,用于操作java中list,set,map等存储结合中的元素。1.stream自己不会存储元素2.stream不会改变源对象,相反,他们会返回一个持有结果的新stream。3.stream操作是延迟执行的&... 查看详情

java8新特性之stream知识分享(代码片段)

优秀博客分享地址:点击进入:(侵权请联系删除)直奔主题1:构造数据集合importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;/***@authorxiexianxin*@create2021-12-0214 查看详情

java8新特性_stream详解(代码片段)

之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行使用Stream简单介绍定义Asequenceofelementssupport... 查看详情