欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自己出的一道java8设计题,让我们一起来学习一下java8的优秀思想

程序员文章站 2022-03-20 23:30:27
  如果你还不熟悉java8的新特性,可以看下下面这篇文章 或者 B站红康师傅讲解的java8新特性,宋红康老师讲的不止有java8哦,乃至java 9-15的新特性都有,可以在B站中找到,或者尚硅谷官网可以免费获取到。 《B站尚硅谷官方运营号地址》想要了解四大类型(Consumer、Supplier、Predicate、Funtion)接口的看下前置文章:  java8新特性—大总结–建议收藏、点赞、加关注!!!如果此前已经掌握了java8的新特性,至少lambda表达式是没啥大问题的。请听题...

  如果你还不熟悉java8的新特性,可以看下下面这篇文章 或者 B站红康师傅讲解的java8新特性,宋红康老师讲的不止有java8哦,乃至java 9-15的新特性都有,可以在B站中找到,或者尚硅谷官网可以免费获取到
 《B站尚硅谷官方运营号地址

想要了解四大类型(Consumer、Supplier、Predicate、Funtion)接口的看下前置文章:

  java8新特性—大总结–建议收藏、点赞、加关注!!!

如果此前已经掌握了java8的新特性,至少lambda表达式是没啥大问题的。

请听题

 要求设计一个计算器,其功能是完成两个数的四则运算(加减乘除)。

例如:有两个操作数 a 和 b 都是double类型的。


初级程序员的写法,具有一定的封装思想。

下面代码看起来没有问题,很nice 对吧。

public class Demo {

    public static void main(String[] args) {
        double a = 12, b = 3, result = 0;
        result = Calculator.run("+", a, b);
        System.out.println("加法 a + b = "+result); // 调用工具类得到结果
        result = Calculator.run("-", a, b);
        System.out.println("减法 a - b = "+result);
        result = Calculator.run("*", a, b);
        System.out.println("乘法 a * b = "+result);
        result = Calculator.run("/", a, b);
        System.out.println("除法 a / b = "+result);
    }
}

/**
 * 封装的一个工具类
 */
class Calculator {
    /**
     * @param operatorString 运算符
     * @param a 操作数1
     * @param b 操作数2
     * @return a,b经过运算符的结果值
     */
    public static double run(String operatorString, double a, double b) {
        if (operatorString.equals("+")) {
            return a + b;
        } else if (operatorString.equals("-")) {
            return a - b;
        } else if (operatorString.equals("*")) {
            return a * b;
        } else if (operatorString.equals("/")) {
            return a / b;
        } else {
            throw new IllegalArgumentException("非法操作符:" + operatorString);
        }
    }
}

 如果你有一些工作经验了,你会发现像这种if-else的写法很不好,看起来很不舒服。或许你会想到用switch进行代替,但依然还是不舒服,因为写在一起,很容易看错,稍微不注意你就会因为这个if-else埋坑。出现bug就很不好改

如果你之前看过我另外一篇文章,利用enmn代替if-else用枚举代替if-else的参考写法

有一定工作经验的程序员写法,利用枚举代替 if-else

import java.util.HashMap;
import java.util.Map;

public class EnmuMode {
    private final static Map<String, String> map;

    static {
        map = new HashMap<>();
        map.put("+", "ADD");
        map.put("-", "SUBTRACT");
        map.put("*", "MULTIPLY");
        map.put("/", "DIVIDION");
    }

    public static void main(String[] args) {
        double a = 12, b = 3, result = 0;
        String option= "*"; // 运算操作

        String strategy = map.getOrDefault(option, "EXCEPTION");// 得到策略字符串
        result = CalculateEnum .valueOf(strategy).calculate(leftNum, rightNum);// 根据策略调用得到对应枚举,调用对应的方法得到计算的结果

        System.out.println(result); // 打印计算后的结果
    }
}

enum CalculateEnum {

    ADD {
        @Override
        public double calculate(double leftNum, double rightNum) {
            return leftNum + rightNum;
        }
    },
    SUBTRACT {
        @Override
        public double calculate(double leftNum, double rightNum) {
            return leftNum - rightNum;
        }
    },
    MULTIPLY {
        @Override
        public double calculate(double leftNum, int rightNum) {
            return leftNum * rightNum;
        }
    },
    DIVIDION {
        @Override
        public double calculate(double leftNum, double rightNum) {
            return leftNum / rightNum;
        }
    },
    EXCEPTION {
        @Override
        public double calculate(double leftNum, double rightNum) {
            throw new IllegalArgumentException("运算操作不支持");
        }
    };

	/**
	 * 将操作数 leftNum,rightNum 运算得到新值
	 * return 计算后的结果值
	 */
    double calculate(double leftNum, double rightNum);

}

而java8程序员的写法

定义一个函数式接口,使用lambda表达式完成功能

public class JAVA8Demo {

    public static void main(String[] args) {
        CalculateImpl calculate = new CalculateImpl(); // 得到计算器的实现类
        double a = 12, b = 3;
        double result = calculate.test((x, y) -> x + y, a, b);
        System.out.println("加法 a+b=" + result);
        double result2 = calculate.test((x, y) -> x - y, a, b);
        System.out.println("减法 a-b=" + result2);
        double result3 = calculate.test((x, y) -> x * y, a, b);
        System.out.println("乘法 a*b=" + result3);
        double result4 = calculate.test((x, y) -> x / y, a, b);
        System.out.println("除法 a/b=" + result4);

    }
}
/**
 * 封装接口类,用于进行java8的数据流传递
 */
class CalculateImpl {
    public double test(Calculate calculate, double a, double b) {
        return calculate.run(a, b); // 将计算后的结果值直接返回
    }
}

/*定义一个函数式接口*/
interface Calculate {
	/**
	 * 调用方法得到a,b的结果值
	 */
    double run(double a, double b);
}

熟悉java8源码的程序员写法

利用 java8 已经提供好的一些常用接口代替自己定义的接口Calculate

public class JAVA8Demo {

    public static void main(String[] args) {
        CalculateImpl calculate = new CalculateImpl();
        double a = 12, b = 3;
        double result = calculate.test((x, y) -> x + y, a, b);
        System.out.println("加法 a+b=" + result);
        double result2 = calculate.test((x, y) -> x - y, a, b);
        System.out.println("减法 a-b=" + result2);
        double result3 = calculate.test((x, y) -> x * y, a, b);
        System.out.println("乘法 a*b=" + result3);
        double result4 = calculate.test((x, y) -> x / y, a, b);
        System.out.println("除法 a/b=" + result4);


    }
}

class Calculator {
    public double test(BiFunction<Double,Double,Double> biFunction, double a, double b) {
        return biFunction.apply(a, b);
    }
}

点评一下上面这些写法的优缺点

  第一种写法,设计简单,通过传入操作符来判断使用那种运算,通过封装,将if-else封装好,但缺点也比较明显,if-else导致代码的可阅读性变差。而且高度耦合。如果要增加求余数等其它运算操作就得直接修改if-else分支源码,如果功能特别多,那么这个if-else就特别长,看都不想看的那种。

  第二种写法,利用枚举代替if-else,这种写法会比if-else的代码阅读性会好一些,这些功能通过构造器被拆分出来,如果也要增加新功能,那么需要增加枚举的构造器,实现抽象方法来完成功能。优点是可以在其它类中复用代码,缺点就也是需要修改源码,具有一定的耦合性,但比第一种好。

  第三种写法,利用函数式编程的思想,设计了一个接口,利用接口将计算后的结果值返回,为了进一步的优化,利用CalculateImpl.test()方法将接口进一步封装,而接口的实现则由lambda表达式完成。从代码量看出,这种写法的代码是最少的,也意味着java8的代码产出量是最大的。与写法一、写法二相比更具可变性,想要增加什么功能就能增加什么功能,缺点就是代码不容易复用,使用lambda表达式增加的功能不好在其它类中复用。也就是不能同对象.调用对应方法完成对应功能。

  第四种写法,是熟悉java8源码的程序员才会的写法,没看过源码或者没见过这种写法的是不会想到这样写。

第四种写法引发了一个问题,你熟悉java8的源码?你知道java8提供了哪些常用函数式接口吗?

也就是下面这张截图,这些接口你知道怎么灵活使用?

自己出的一道java8设计题,让我们一起来学习一下java8的优秀思想

本文地址:https://blog.csdn.net/qq_41813208/article/details/110791665