IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 枚举和Lambda表达式 -> 正文阅读

[Java知识库]枚举和Lambda表达式

1.枚举

????????枚举是在 JDK 1.5 引?的,主要是用来表示?组相同业务的值,比如我们要实现卖车的程序,我们要定义?组颜色来穷举这辆?所提供的所有颜色,在没有枚举之前,我们是这样实现的:

public static int final RED = 1;
public static int final GREEN = 2;
public static int final BLACK = 3;

以上代码存在的主要问题有以下 3 个:

  1. 代码可读性低,?如,当我们看到数字 2 时,并不能准确的知道它代表的具体是什么颜?,我们要去代码??查;
  2. 参数传递很容易出错,以上代码类型为 int,所以在传递时理论上是可以接受所有的 int 值的,但只有部分值是有效的颜?,所有很容易传递值出错;
  3. 写法不够优雅,在外层(外边类)调?时,看到的都是?个个?魔法数字?,很让?很疑惑。

但有了?枚举?之后,我们就可以使?以下代码来组织所有的颜?了:

public enum ColorEnum { 
    RED, GREEN, BLACK;
}

它的优点有以下几个:

  1. 增强了代码的可读性;
  2. 减少了传递参数的错误概率;
  3. switch 判断更?便,语法清晰;
  4. 代码?够简洁、优雅。

?

1.1 switch 判断

public enum ColorEnum { 
    RED, GREEN, BLACK;

    public static void main(String[] args) { 
        ColorEnum colorEnum = ColorEnum.GREEN;
        switch (colorEnum) {
            case RED:
                System.out.println("红?");
                break;
            case BLACK:
                System.out.println("??");
                break;
            case GREEN:
                System.out.println("绿?");
                break;
            default:
                System.out.println("其他颜?");
                break;
        }
 ?  }
}

?运行结果:

?

1.2 枚举的常用方法

?1.2.1 values() 使用

以数组形式返回枚举类型的所有成员。

public enum ColorEnum {
    RED, GREEN, BLACK;

    public static void main(String[] args) {
        for (ColorEnum colorEnum : ColorEnum.values()) {
            System.out.println(colorEnum);
        }
    }
}

执行结果:

1.2.2?ordinal() 使用

public enum ColorEnum2 {
    RED, GREEN, BLACK;

    public static void main(String[] args) {
        for (ColorEnum colorEnum : ColorEnum.values()) {
            System.out.println(colorEnum + ":" + colorEnum.ordinal());
        }
    }
}

执行结果:?

?1.2.3 valueOf() 使用

将普通字符串转换为枚举实例。

public enum ColorEnum3 {
    RED, GREEN, BLACK;

    public static void main(String[] args) {
        ColorEnum color = ColorEnum.valueOf("BLACK");
        System.out.println(color.ordinal());
    }
}

执行结果:

?

1.2.3?compareTo() 使用

比较两个枚举成员在定义时的顺序,返回值为 枚举成员下标差值的int值。

public enum ColorEnum4 {
    RED, GREEN, BLACK;

    public static void main(String[] args) {
        ColorEnum4 color1 = ColorEnum4.RED;
        ColorEnum4 color2 = ColorEnum4.GREEN;
        ColorEnum4 color3 = ColorEnum4.BLACK;

        System.out.println("红色对比绿色:" + color1.compareTo(color2));
        System.out.println("红色对比黑色:" + color1.compareTo(color3));
        System.out.println("绿色对比黑色:" + color2.compareTo(color3));
        System.out.println("绿色对比红色:" + color2.compareTo(color1));
        System.out.println("黑色对比红色:" + color3.compareTo(color1));
        System.out.println("黑色对比绿色:" + color3.compareTo(color2));
    }
}

?运行结果:

?

1.3 枚举优缺点

优点:

  1. 增强了代码的可读性;
  2. 减少了传递参数的错误概率;
  3. switch 判断更?便,语法清晰;
  4. 代码?够简洁、优雅;
  5. 枚举有内置?法,功能更强?。

?缺点

  1. 不可继承,?法扩展。

?

?2.Lambda 表达式

????????Lambda 表达式是 JDK 8 中?个重要的新特性,lambda 表达式允许你通过表达式来代替功能接口(通过表达式通过实现业务功能)。lambda 表达式就和?法?样,它提供了?个正常的参数列表和?个使?这些参数的主体(body,可以是?个表达式或?个代码块),Lambda 表达式(Lambda expression)可以看作是?个?匿名函数?。?

2.1 为什么要用?Lambda

原因有三个

  1. 提供了更简单的语法和写代码的?式;
  2. 取代匿名内部类;
  3. 简化代码,干净整洁。

?

2.2 Lambda 语法

2.2.1 Lambda 表达式的基本语法如下:

(?参) -> {实现代码}

表达式由 3 部分组成:

  1. 入参 paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有?个推断类型时可以省略掉圆括号;
  2. ->:可理解为“被?于”的意思;
  3. 实现代码(方法体):可以是表达式也可以代码块,是函数式接???法的实现。代码块可返回?个值或者什么都不反回,这?的代码块块等同于?法的?法体。如果是表达式,也可以返回?个值或者什么都不返回。

?2.2.2 Lambda 基础使用:

    public static void main(String[] args) {
        List<String> lists = Arrays.asList("Hello", "World", "Java");
        // 没使? lambda 之前
        for (String list : lists) {
            System.out.println(list);
        }
        System.out.println();
        // 使? lambda 之后
        lists.forEach(s -> System.out.println(s));
    }

注意事项

  1. 如果 lambda 参数的小括号里面只有?个参数,那么小括号可以省略;
  2. 如果?法体当中只有?句代码,那么?括号可以省略;
  3. 如果?法体中只有?条语句,其是 return 语句,那么?括号可以省略,且去掉 return 关键字。

?

2.3 Lambda 和函数式接口

?Lambda 表达式的写法有很多,比如以下这些:

// 1. 不需要参数,返回值为 2 
() -> 2

// 2. 接收?个参数(数字类型),返回其2倍的值 
x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的和 
(x, y) -> x + y

// 4. 接收2个int型整数,返回他们的乘积 
(int x, int y) -> x * y

// 5. 接受?个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) 
(String s) -> System.out.print(s)

但是Lambda 表达式不能直接使用,它在使用之前必须初始化,lambda 表达式必须借助 函数式接口(@FunctionalInterface)来初始化。

?

函数式接口:

定义:?个有且只有?个抽象方法的接口。

?函数式接口的定义代码如下

@FunctionalInterface
    interface MyFunctionalInterface { 
        void myMethod(Object... args);
}

?注意事项

  1. 如果?个接口只有?个抽象?法,那么该接口就是?个函数式接口;
  2. 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接?的定义来要求该接?,这样如果有两个抽象?法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接?中只有?个抽象方法,你可以不加这个注解。加上就会?动进?检测的。

??有了函数式接口之后,我们就可以使用?lambda 表达式对其实例化了,实现代码如下:?

@FunctionalInterface
interface MyFunctionalInterface {
    void myMethod(Object... args);
}

public class LambdaExample {
    public static void main(String[] args) {
        // lambda 表达式借助函数式接?初始化
        MyFunctionalInterface functionalInterface = (objects) -> {
            for (Object o : objects) {
                System.out.println(o.toString());
            }
        };
        // 执? lambda 表达式
        functionalInterface.myMethod("张三", "李四", "王五");
    }
}

执行结果:

?

2.4 Lambda 的变量捕获

????????在 lambda 中获取变量和在匿名内部类获取变量的规则?致:也就是在 lambda 中,如果要获取外部的变量,那么这个变量要么是被 final 修饰,如果不是被 final 修饰的,要保证在使用之前,没有修改,否则就会报错

@FunctionalInterface
interface MyFunctionalInterface {
    void myMethod(Object... args);
}

public class LambdaExample {
    public static void main(String[] args) {
        int count = 10;
        MyFunctionalInterface functionalInterface = (objects) -> {
            // count = 99; // 在使?之前,如果修改就会报错
            for (Object o : objects) {
                System.out.println(o.toString());
            }
            System.out.println("打印外部变量:" + count); // 可以正常执?
        };
        functionalInterface.myMethod("张三", "李四", "王五");
    }
}

?运行结果:

将 count 值修改为 99 后会报错:

?

?2.5 Lambda 在集合中的使用

?????????Lambda 表达式最有价值的作?就是可以配合集合?块使?。Lambda 可以配合使?的?法列表如下:

2.5.1 Map 中的 forEach

        HashMap<String, String> map = new HashMap<String, String>() {{
            put("name", "Java");
            put("desc", "Good");
        }};
        
        // jdk 1.8 之前
        for (Map.Entry<String, String> item : map.entrySet()) {
            System.out.println(item.getKey() + ":" + item.getValue());
        }
        System.out.println();
        
        // lambda
        map.forEach((k, v) -> System.out.println(k + ":" + v));

?2.5.2 List 排序

        List<Integer> list = Arrays.asList(5, 3, 2, 7, 9);
        System.out.println("排序前:" + list);

        // 不使用 Lambda 表达式
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        // 使用 Lambda 表达式
        list.sort((o1, o2) -> o2 - o1);

        System.out.println("排序后:" + list);

2.5.3 List 查找

        List<String> list = Arrays.asList("Java", "Lambda", "Spring", "Lambda", "SpringBoot", "MyBatis");

        // 1.8 之前
        for (String item : list) {
            if (item.equals("Lambda")) {
                System.out.println("");
            }
        }

        // lambda
        List<String> finds = list.stream().filter(s -> s.equals("Lambda")).collect(Collectors.toList());
        System.out.println(finds);

?

2.6 Lambda 优缺点分析

优点

  1. 代码简洁,开发迅速;
  2. 方便函数式编程;
  3. 非常容易进行并行计算;
  4. Java 引? Lambda,改善了集合操作。

缺点?

  1. 代码可读性变差;
  2. 在非并行计算中,很多计算未必有传统的 for 性能要高;
  3. 不容易进行调试。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:30:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:05:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码