枚举和Lambda表达式

目录

1.枚举

1.1 switch 判断

1.2 枚举的常用方法

 1.2.1 values() 使用

1.2.2 ordinal() 使用

 1.2.3 valueOf() 使用

1.2.3 compareTo() 使用

1.3 枚举优缺点

 2.Lambda 表达式

2.1 为什么要用 Lambda

2.2 Lambda 语法

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

 2.2.2 Lambda 基础使用:

2.3 Lambda 和函数式接口

2.4 Lambda 的变量捕获

 2.5 Lambda 在集合中的使用

2.5.1 Map 中的 forEach

 2.5.2 List 排序

2.5.3 List 查找

2.6 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. 不容易进行调试。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

澄白易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值