JavaEE阶段——枚举和Lambda表达式

51 阅读6分钟

一、枚举

1、定义

枚举是在JDK1.5引入的,主要是用来表示一组相同业务的值。 (enum 与类的命名规则一样——大驼峰)

2、使用方式

命名格式:所有的枚举值使用全部字母大写的形式定义

public enum ColorEnum {
    RED,GREEN,BLACK;
}

3、优点

(1)增加了代码的可读性;

(2)减少了传递参数的错误率;

(3)使用枚举,那么switch的写法会非常简单并且语义也非常清晰;

(4)代码足够简洁、优雅;

(5)内置了很多方法,功能更强大。

4、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;
        }
    }
}

4、枚举常用方法

方法名称描述
values()以数组形式返回枚举类型的所有成员
ordinal()获取枚举成员索引的位置(从0开始)
valueOf()将普通字符串转换为枚举类型
compareTo()比较两个枚举成员在定义时的顺序

1、values()的使用

(1)代码示例:

public class App {
    public static void main(String[] args) {
        eachEnum();
    }
    /**
     * 循环打印所有的枚举类型
     */
    private static void eachEnum() {
        //得到所有的枚举类型
        ColorEnum[] ars = ColorEnum.values();
        for (ColorEnum item : ars){
            System.out.println(item);
        }
    }
}

(2)运行截图:

image.png

2、ordinal()的使用

(1)代码示例:

private static void eachEnum() {
    //得到所有的枚举类型
    ColorEnum[] ars = ColorEnum.values();
    for (ColorEnum item : ars){
        //返回当前枚举示例的下标
        int enumIdx = item.ordinal();
        System.out.println(item + ":" + enumIdx);
    }
}

(2)运行截图:

image.png

3、valueOf()的使用

(1)代码示例1:

public static void main(String[] args) {
    String color = "RED";
    //将字符转化为枚举实例
    ColorEnum colorEnum = ColorEnum.valueOf(color);
    printColor(colorEnum);
}

    private static void printColor(ColorEnum colorEnum) {
        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;
        }
    }

补充: 输入的字符串无效时

public static void main(String[] args) {
    //若输入的字符串无效
    String color = "RDE";
    try{
        ColorEnum colorEnum = ColorEnum.valueOf(color);
        printColor(colorEnum);
    }catch (Exception e){
        System.out.println("枚举类型转换失败");
    }
}

(2)运行截图:

image.png

4、compareTo()的使用

注意: 对比的是下标,大于返回1,等于返回0,小于返回-1;(例如:若红色比蓝色,返回值为-2,差为0-2)

(1)代码示例:

public static void main(String[] args) {
    ColorEnum colorEnum1 = ColorEnum.GREEN;
    ColorEnum colorEnum2 = ColorEnum.RED;
    ColorEnum colorEnum3 = ColorEnum.BLACK;
    System.out.println("颜色顺序是:红色、绿色、黑色");
    //绿色对比红色:1
    int result1 = ColorEnum.GREEN.compareTo(colorEnum2);
    System.out.println("绿色对比红色:" + result1);
    //绿色对比绿色:0
    int result2 = ColorEnum.GREEN.compareTo(colorEnum1);
    System.out.println("绿色对比绿色:" + result2);
    //绿色对比黑色:-1
    int result3 = ColorEnum.GREEN.compareTo(colorEnum3);
    System.out.println("绿色对比黑色:" + result3);
}

(2)运行截图:

image.png

5、缺点

不可继承,无法扩展

二、Lambda表达式

1、定义

Lambda表达式是JDK8中一个重要的新特性,Lambda表达式允许你通过表达式来代替功能接口。Lambda表达式就和方法一样,它提供了它提供了一个正常的参数列表和一个使用这些参数的主体(可以是一个表达式或者一个代码块),Lambda表达式可以看做是一个匿名函数。

2、优点

(1)提供了更简单的语法和写代码的方式;

(2)取代匿名内部类;

(3)简化代码,干净整洁。

3、语法

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

(1)入参:类似于方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号;

(2)->:可以理解为“被用于”的意思;

(3)实现代码:可以是表达式也可以是代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不返回,这里的代码块等同于方法中的方法体。如果是表达式,也可以返回一个值或者什么都不返回。

4、Lambda表达式基础使用

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

public class LambdaExample {
    public static void main(String[] args) {
        List<String> lists = Arrays.asList("A","B","C","D");
        //没使用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关键字。

5、函数式接口

1、Lambda和函数式接口

//1、不需要参数,返回值为2
()->2
//2、接收一个参数(数值类型),返回其2倍的值
()->2*x
//3、接受两个参数(数字),并返回它们的和
(x,y)-> x+y
//4、接收两个int型整数,返回它们的乘
(int x, int y)->x*y
//5、接受一个string对象,并在控制台打印,不返回任何值
(String s )-> System.out.println(s)

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

2、函数式接口

1、定义:一个接口有且只有一个抽象方法。

2、自定义函数式接口:

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

3、使用Lambda表达式对其进行实例化:

(1)代码示例:

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

(2)运行截图:

image.png

6、Lambda的变量获取

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

1、第一种:

(1)代码示例

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

(2)运行截图:

image.png 2、第二种:

(1)代码示例

public class LambdaExample {
    public static void main(String[] args) {
        final int[] count = new int[1];
        MyFunctionalInterface myFunctionalInterface= (objects)-> {
            count[0] = 100;
            for (Object o : objects) {
                System.out.println(o.toString());
            }
            System.out.println("打印外部变量:"+ count[0]);
        };
            myFunctionalInterface .myMethod("张三","李四","王麻子");
        };
    }

(2)运行截图:

image.png

7、Lambda在集合中的使用

1、Map中的forEach

1、JDK8之前的写法:

(1)代码示例

import java.util.HashMap;
import java.util.Map;
public class LambdaExample {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap() {{
            put("name", "Java");
            put("desc", "Good");
        }};
        //jdk8之前写法
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

(2)运行截图:

image.png 2、有了Lambda之后的写法:

(1)代码示例:

import java.util.HashMap;
public class LambdaExample {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap() {{
            put("name", "Java");
            put("desc", "Good");
        }};
        map.forEach((k,v) -> {System.out.println(k + ":" + v);});
    }
}

(2)运行截图:

image.png

2、List排序

(1)代码示例:

import java.util.*;

public class LambdaExample {
    public static void main(String[] args) {
        List<Integer> lists = new ArrayList(){{
            add(1);
            add(3);
            add(7);
            add(6);
            add(4);
        }};
        //排序前的顺序[1, 3, 7, 6, 4]
        System.out.println(lists);
        lists.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //正序[1, 3, 4, 6, 7]
                return o1 - o2;
                //逆序[7, 6, 4, 3, 1]
//                return o2 -o1;
            }
        });
        System.out.println(lists);
    }
}

(2)运行截图:

image.png

3、List查找

(1)代码示例:

import java.util.*;
import java.util.stream.Collectors;

public class LambdaExample {
    public static void main(String[] args) {
        List<String> lists = new ArrayList<String>(){{
            add("Java");
            add("C++");
            add("Spring");
        }};
        System.out.println(lists);
        List<String> javaItem = lists.stream().filter(s -> s.equals("Java")).collect(Collectors.toList());
        System.out.println(javaItem);
    }
}

(2)运行截图:

image.png 总结:Lambda最大的价值是可以配合集合进行使用,比如循环、排序、查找等实现。

8、缺点

(1)代码可读性变差; (2)在非并行计算中,很多计算未必有传统的for性能更高; (3)不容易进行调试。