JDK8的特性

JDK8的特性

 1. Lambda表达式
 2. 函数式接口
 3. 方法引用。
 4. Stream流
 5. 日期时间类

1.Lambda表达式

1.1 lambda的由来

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/13 16:07
 */
public class Test01 {
    public static void main(String[] args) {
        //开启一个线程 该构造函数需要传递一个Runnable类型的接口参数
        Thread thread = new Thread(new My());
        //开启线程
        thread.start();

        //匿名内部类
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("通过匿名内部类实现线程任务");
            }
        });
        //开启线程
        thread1.start();
    }
}
class My implements Runnable{

    @Override
    public void run() {
        System.out.println("使用实现类来完成线程任务");
    }
}

分析:

  1. Thread类需要一个Runnable接口作为参数,其中的抽象方法run方法是用来指定线程任务内容的核心方法,并且Runnable接口中有且只有一个抽象方法

  2. 为了指定run方法体,不得不需要Runnable的实现类

  3. 为了省去定义一个Runnable 的实现类,不得不使用匿名内部类

  4. 必须覆盖重写抽象的run方法,所有的方法名称,方法参数,方法返回值不得不都重写一遍,而且不能出错,

  5. 而实际上,我们只在乎方法体中的代码.

我们可以使用lambda表达式来完成上面的功能。

1.2 lambda表达式初体验

//lambda表达式
Runnable runnable = ()->{
    System.out.println("lambda表达式完成线程任务");
};
//将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread thread2 = new Thread(runnable);
//开启线程
thread2.start();

1.3 lambda表达式的语法

lambda省去了面向对象的条条框框,lambda的标注格式有3个部分组成:

  • Lambda表达式的基础语法

  • Lambda是一个匿名函数 一般关注的是以下两个重点

  • 参数列表 方法体

  • 组成Lambda表达式的三要素:参数,箭头,代码块

  • (参数列表)->{}

  • ():用来描述参数列表 如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可

  • ->: Lambda运算符 连接符 连接的是参数以及方法体

  • {}:用来描述方法体 有时可以省略

1.4 练习

  • Lambda表达式的使用前提 ①、有一个接口 ②、接口中有且仅有一个抽象方法

(1)抽象方法无参无返回值

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/13 17:04
 */
public class Test02 {
    public static void main(String[] args) {
        //主函数调用fun方法。第一种:创建UserService接口的实现类,并且创建该类的实现对象
        //创建UserServiceImpl的实现对象
        UserServiceImpl userService = new UserServiceImpl();
        userService.show();

        //第二种:匿名内部类的方式
        UserService userService1 = new UserService() {
            @Override
            public void show() {
                System.out.println("这是匿名内部类的show方法的实现");
            }
        };
        fun(userService1);

        //第三种:lambda表达式--该接口必须为函数式接口
        UserService userService2=()->{
            System.out.println("这是lambda表达式的show方法");
        };
        fun(userService2);
    }
    public static void fun(UserService userService){
        userService.show();
    }
}


@FunctionalInterface
interface UserService{
    /**
     * 函数式接口(FunctionalInterface)-->里面有且只有一个抽象方法。
     * 只有这种接口才能使用lambda表达式。
     */
    public void  show();
}
class UserServiceImpl implements UserService{
    @Override
    public void show() {
        System.out.println("这是USerService的实现类的show方法");
    }
}

(2)抽象方法有参有返回值

Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、查找替换和复制等操作.

Collections 提供了如下方法用于对 List 集合元素进行排序。

  • void reverse(List list):对指定 List 集合元素进行逆向排序。

  • void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。

  • void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。

  • void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。

  • void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。

  • void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/13 18:31
 */
public class Test03 {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("张三",55));
        personList.add(new Person("李四",5));
        personList.add(new Person("王五",65));
        personList.add(new Person("赵六",15));
        personList.add(new Person("刘强",45));
        //对集合中的元素按照年龄排序,由小到大
        System.out.println(personList);
        //Collections:集合工具类,--匿名内部类
//        Comparator<Person> comparator = new Comparator<Person>() {
//            @Override//如果是0表示相同 大于0表示o1大于o2
//            public int compare(Person o1, Person o2) {
//                return o1.getAge()-o2.getAge();
//            }
//        };
//        Collections.sort(personList,comparator);
//        System.out.println(personList);
        //lambda表达式就是对函数式接口中的抽象方法的简写
        Collections.sort(personList,(o1, o2) -> {
            return o1.getAge()- o2.getAge();
        });
        System.out.println(personList);
    }
}
class Person{
    private String name;
    private Integer age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

(3)抽象方法有参无返回值

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/13 20:34
 */
public class Test04 {
    public static void main(String[] args) {
        //匿名内部类
        EmpService empService=new EmpService() {
            @Override
            public void eat(String food) {
                System.out.println("烧烤");
            }
        };
        fun(empService);
        //lambda表达式
        EmpService empService1=(f)->{
            System.out.println("爆炒鸡");
        };
        fun(empService1);
    }
    public static void fun(EmpService empService){
        empService.eat("龙虾");
    }
}
interface EmpService{
    public void eat(String food);
}

1.5 Lambda表达式的省略写法

在lambda表达式的标准写法基础上,可以使用省略写法规则为: ①、小括号内的参数类型可以省略。但是有多个参数的情况下,不能只省略一个 ②、如果小括号内有且仅有一个参数,那么小括号可以省略 ③、如果代码块的语句有且仅有一条,可以同时省略大括号、return关键字以及分号。

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/13 20:47
 */
public class Test05 {
    public static void main(String[] args) {
        Us u=a -> System.out.println("你好明天:"+a);
        fun(u);
//        Us2 us2=a -> {return a*2;};
        //默认lambda表达式就会把最后一条语句作为返回结果。
//        Us2 us2=a -> a*2;
//        fun02(us2);
        fun02(a -> a*2);
    }
    public static void fun(Us us){
        us.show(15);
    }
    public static void fun02(Us2 us2){
        System.out.println(us2.print(25));
    }
}
interface Us{
    public void show(int a);
}
interface Us2{
    public int print(int a);
}

1.6 Lambda表达式使用的前提

 Lambda表达式的语法是非常简洁的,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意

  1. 方法的参数或局部变量类型必须为接口才能使用Lambda

  2. 接口中有且仅有一个抽象方法(@FunctionalInterface)

后面我们使用lambda表达式主要核心使用再Stream流中。

2.内置函数式接口

要想使用lambda表达式它的前提就是必须是函数式接口。

2.1 内置函数式接口的由来

/**
 * @Description:
 * @Author: Zhou
 * @CreateTime: 2023/6/14 14:04
 */
public class Test {
    public static void main(String[] args) {
        Operation o=arr -> {
            int sum=0;
            for (int s : arr) {
                sum+=s;
            }
            return sum;
        };
        fun(o);
    }
    public static void fun(Operation operation){
        int[] arr={1,2,3,4};
        int sum= operation.getSum(arr);
        System.out.println("数组的和:"+sum);
    }
}
@FunctionalInterface
interface Operation
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的使用 JDK 8 特性进行级联查询树的例子: ```java public class TreeNode { private Long id; private Long parentId; private String name; private List<TreeNode> children = new ArrayList<>(); // 构造函数、getter 和 setter 方法省略 // 添加子节点 public void addChild(TreeNode node) { children.add(node); } // 获取子节点 public List<TreeNode> getChildren() { return children; } // 级联查询树 public static List<TreeNode> buildTree(List<TreeNode> nodes) { Map<Long, TreeNode> nodeMap = nodes.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity())); List<TreeNode> rootNodes = new ArrayList<>(); for (TreeNode node : nodes) { Long parentId = node.getParentId(); if (parentId == null) { rootNodes.add(node); } else { TreeNode parent = nodeMap.get(parentId); parent.addChild(node); } } return rootNodes; } } ``` 使用上述代码,我们可以将一个节点列表转换为树形结构。例如,如果我们有以下节点列表: ```java List<TreeNode> nodes = Arrays.asList( new TreeNode(1L, null, "A"), new TreeNode(2L, 1L, "B"), new TreeNode(3L, 1L, "C"), new TreeNode(4L, 2L, "D"), new TreeNode(5L, 2L, "E"), new TreeNode(6L, 3L, "F") ); ``` 我们可以使用 `TreeNode.buildTree(nodes)` 方法将其转换为树形结构: ```java List<TreeNode> rootNodes = TreeNode.buildTree(nodes); System.out.println(rootNodes); ``` 输出结果为: ``` [TreeNode(id=1, parentId=null, name=A, children=[TreeNode(id=2, parentId=1, name=B, children=[TreeNode(id=4, parentId=2, name=D, children=[]), TreeNode(id=5, parentId=2, name=E, children=[])]) TreeNode(id=3, parentId=1, name=C, children=[TreeNode(id=6, parentId=3, name=F, children=[])])])] ``` 这个例子中,我们使用了 Java 8 的 Lambda 表达式和 Stream API 来简化代码。其中,`Collectors.toMap()` 方法将节点列表转换为一个以节点 ID 为键、节点对象为值的 Map,方便后续查找父节点。然后,我们遍历节点列表,将每个节点添加到其父节点的 `children` 列表中,最终返回所有根节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值