0
点赞
收藏
分享

微信扫一扫

枚举和Lambda表达式介绍

捡历史的小木板 2022-04-21 阅读 47
java

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.2 枚举常⽤⽅法

 (1)values() 使⽤

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

private static void eachEnum(){
        ColorEnum[] arrs = ColorEnum.values();
        for (ColorEnum item : arrs){
            System.out.println(item);
        }


    }

(2)ordinal() 使⽤

获取枚举成员的索引位置。

  private static void eachEnum(){
        
        ColorEnum[] arrs = ColorEnum.values();
        for (ColorEnum item : arrs){
            int enumIdx = item.ordinal();
            System.out.println(item + ":" + enumIdx);
        }


    }

(3)valueOf() 使⽤

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

public static void main(String[] args) {
     //   printColor(ColorEnum.GREEN);
      //  eachEnum();
        String color = "RED";
        try {
            //将字符串转换成枚举示例
            ColorEnum colorEnum = ColorEnum.valueOf(color);
            printColor(colorEnum);
        }catch(Exception e){
            System.out.println("枚举类型转换失败");
        }
    }

(4)compareTo() 使⽤

⽐较两个枚举成员在定义时的顺序,返回值为 -1/0/1。

 ColorEnum colorEnum = ColorEnum.GREEN;
        ColorEnum colorEnum2 = ColorEnum.RED;
        ColorEnum colorEnum3 = ColorEnum.BLACK;
        System.out.println("颜色的顺序:红色,绿色,黑色");
        int result1 = colorEnum.compareTo(colorEnum2);
        System.out.println("绿色对比红色:" + result1);
        int result2 = colorEnum.compareTo(colorEnum);
        System.out.println("绿色对比绿色:" + result2);
        int result3 = colorEnum2.compareTo(colorEnum3);
        System.out.println("红色对比黑色:"  + result3);

(5)枚举优缺点

优点:1. 增强了代码的可读性。

           2. 减少了传递参数的错误概率。

           3. switch 判断更⽅便,语法清晰。

           4. 代码⾜够简洁、优雅。

           5. 枚举有内置⽅法,功能更强⼤。

缺点:不可继承,⽆法扩展。

 2.Lambda 表达式

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

2.1 为什么要⽤ Lambda?

1. 提供了更简单的语法和写代码的⽅式。

2. 取代匿名内部类。

3. 简化代码,⼲净整洁。

2.2 Lambda 语法

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

表达式由 3 部分组成:

1. ⼊参 paramaters:类似⽅法中的形参列表,这⾥的参数是函数式接⼝⾥的参数。这⾥的参数 类型可以明确的声明也可不声明⽽由JVM隐含的推断。另外当只有⼀个推断类型时可以省略 掉圆括号。

2. ->:可理解为“被⽤于”的意思

3. 实现代码(⽅法体):可以是表达式也可以代码块,是函数式接⼝⾥⽅法的实现。代码块可 返回⼀个值或者什么都不反回,这⾥的代码块块等同于⽅法的⽅法体。如果是表达式,也可 以返回⼀个值或者什么都不返回。

Lambda 基础使⽤:

import java.util.Arrays;
import java.util.List;

public class LambdaTest {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Java", "MySQL", "Spring");
        //传统的循环并打印
        for (String item : list) {
            System.out.println(item);
        }
        //lambda
        list.forEach((item) ->{
            System.out.println(item);
        });
        //简洁
        list.forEach(item -> System.out.println(item));
    }

}

注意事项: 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 表达式不能直接使⽤,它在使⽤之前必须初始化,lambda 表达式必须借助函数式接⼝来初始化。

2.3.1 函数式接⼝

函数式接⼝定义:⼀个接⼝有且只有⼀个抽象⽅法。

注意事项:

1. 如果⼀个接⼝只有⼀个抽象⽅法,那么该接⼝就是⼀个函数式接⼝。

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

函数式接⼝的定义代码如下:

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

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

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 修饰的,要保证在使⽤之前,没有修改,否 则就会报错。

public class LambdaTest {
    public static void main(String[] args) {
int count = 100;
          MyFunctionalInterface myFunctionalInterface = (o) ->{
              for (Object item : o){
                  System.out.println("item:" + item);
              }
              System.out.println("Count:" + count);
          };
          myFunctionalInterface.myMethod("java","mysql","html");
    }

}

2.5 Lambda 在集合中的使⽤

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

 Map的用法:

 HashMap<String,String> map = new HashMap<String,String>(){{
            put("java","java Value");
            put("MySQL","MySQL Value");
        }};
        //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);
        });

List 排序

List<Integer> list = Arrays.asList(5,3,4,6,7);
        System.out.println("排序前:" + list);
list.sort(((o1, o2) -> {
            return o1-o2;
        }));
        System.out.println("排序后: " + list);

List 查找

List<String> list = Arrays.asList("java","MySQL","Spring");
List<String> finds = list.stream().filter(s->s.equals("Spring")).collect(Collectors.toList());
        System.out.println(finds);

2.6 Lambda 优缺点分

优点: 1. 代码简洁,开发迅速

            2. ⽅便函数式编程

            3. ⾮常容易进⾏并⾏计算

            4. Java 引⼊ Lambda,改善了集合操作

缺点:1. 代码可读性变差

           2. 在⾮并⾏计算中,很多计算未必有传统的 for 性能要⾼

           3. 不容易进⾏调试

 

举报

相关推荐

0 条评论