如何在Java 8中使用参数调用方法?

时间:2017-01-05 21:06:21

标签: java

我正在做练习,我提示用户给我选择的操作员和两个不同的数字,然后输出结果。我知道我可以使用if else或switch case轻松地进行这项练习,但我真的很想让它以这种方式工作。问题在于我的操作符方法,显然在Java中,您无法传入参数并使用该参数来调用方法。有没有办法让这项工作?如果你对这个问题感到困惑,我很乐意澄清。

import java.util.Scanner;

public class methods {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Welcome, choose your operator, would you like to add, subtract, multiply, or divide?");
        String typeofOperator = sc.nextLine();
        System.out.print("Enter the first number: ");
        int firstNumber = sc.nextInt();
        System.out.print("Enter the second number: ");
        int secondNumber = sc.nextInt();
        operator(typeofOperator, firstNumber, secondNumber);
    }

    public static void operator(String typeofOperator, int firstNumber, int secondNumber) {
        typeofOperator(firstNumber, secondNumber);
    }

    public static int add(int firstNumber, int secondNumber) {
        int answer = firstNumber + secondNumber;
        result(answer);
    }
    public static int subtract(int firstNumber, int secondNumber) {
        int answer = firstNumber - secondNumber;
        result(answer);
    }
    public static int multiply(int firstNumber, int secondNumber) {
        int answer = firstNumber * secondNumber;
        result(answer);
    }
    public static int divide(int firstNumber, int secondNumber) {
        int answer = firstNumber / secondNumber;
        result(answer);
    }
    public static void result(int result) {
        System.out.println("This is the result: " + result);
    }
}

6 个答案:

答案 0 :(得分:5)

使用带功能的地图。它将采用Java 8风格:

public class methods {

    private static Map<String, BiFunction<Integer, Integer, Integer>> OPERATOR_MAP = new HashMap<>();
    static {
        OPERATOR_MAP.put("add", methods::add);
        OPERATOR_MAP.put("subtract", methods::subtract);
        OPERATOR_MAP.put("multiply", methods::multiply);
        OPERATOR_MAP.put("divide", methods::divide);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Welcome, choose your operator, would you like to add, subtract, multiply, or divide?");
        String typeofOperator = sc.nextLine();
        System.out.print("Enter the first number: ");
        int firstNumber = sc.nextInt();
        System.out.print("Enter the second number: ");
        int secondNumber = sc.nextInt();
        operator(typeofOperator, firstNumber, secondNumber);
    }

    public static void operator(String typeofOperator, int firstNumber, int secondNumber) {
        OPERATOR_MAP.get(typeofOperator).apply(firstNumber, secondNumber);
    }

    public static int add(int firstNumber, int secondNumber) {
        int answer = firstNumber + secondNumber;
        result(answer);
        return 0;
    }
    public static int subtract(int firstNumber, int secondNumber) {
        int answer = firstNumber - secondNumber;
        result(answer);
        return 0;
    }
    public static int multiply(int firstNumber, int secondNumber) {
        int answer = firstNumber * secondNumber;
        result(answer);
        return 0;
    }
    public static int divide(int firstNumber, int secondNumber) {
        int answer = firstNumber / secondNumber;
        result(answer);
        return 0;
    }
    public static void result(int result) {
        System.out.println("This is the result: " + result);
    }
}

当然,没有检查用户是否可以指定不存在的运算符。

更新:添加&#34;返回0&#34;所有运算符方法,使代码可编译。我只是想对原始代码进行微小的更改,以指定如何达到所需功能的方式。

UPDATE2:如果不需要操作员方法,那么我想更简单地写一下:

public class methods {

    private static Map<String, BiFunction<Integer, Integer, Integer>> OPERATOR_MAP = new HashMap<>();
    static {
        OPERATOR_MAP.put("add", (x, y) -> x + y);
        OPERATOR_MAP.put("subtract", (x, y) -> x - y);
        OPERATOR_MAP.put("multiply", (x, y) -> x * y);
        OPERATOR_MAP.put("divide", (x, y) -> x / y);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Welcome, choose your operator, would you like to add, subtract, multiply, or divide?");
        String typeofOperator = sc.nextLine();
        System.out.print("Enter the first number: ");
        int firstNumber = sc.nextInt();
        System.out.print("Enter the second number: ");
        int secondNumber = sc.nextInt();
        System.out.println(OPERATOR_MAP.get(typeofOperator).apply(firstNumber, secondNumber));
    }
}

答案 1 :(得分:2)

  在Java中,您无法传入参数并使用该参数来调用   方法

好吧,你可以开始执行if / else,并根据operator-type找出应该调用哪个方法。也就是说,感觉像面向对象的方法会更清晰:

我们可以定义Operator接口:

interface Operator {
    int call(int first, int second);
}

然后创建实现它的类:每个操作一个:

class Add implements Operator {
    @Override
    public int call(int first, int second) {
        return first + second;
    }
}

class Subtract implements Operator {
    @Override
    public int call(int first, int second) {
        return first - second;
    }
}

class Multiply implements Operator {
    @Override
    public int call(int first, int second) {
        return first * second;
    }
}

class Divide implements Operator {
    @Override
    public int call(int first, int second) {
        return first / second;
    }
}

现在我们需要一个工厂,它将接收运算符类型作为参数,并分别创建相关的运算符对象。一种方法是:

class OperatorFactory {
    static Operator build(String type) {
        Operator res;
        type = type.trim();
        switch (type) {
            case "add":
                res = new Add();
                break;
            case "subtract":
                res = new Subtract();
                break;
            case "multiply":
                res = new Multiply();
                break;
            case "divide":
                res = new Divide();
                break;
            default:
                throw new IllegalArgumentException(type);
        }
        return res;
    }
}

让我们看看代码的工作原理:

public class Methods {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Welcome, choose your operator, would you like to add, subtract, multiply, or divide?");
        String typeofOperator = sc.nextLine();
        System.out.print("Enter the first number: ");
        int firstNumber = sc.nextInt();
        System.out.print("Enter the second number: ");
        int secondNumber = sc.nextInt();
        operator(typeofOperator, firstNumber, secondNumber);
    }

    static void operator(String typeOfOperator, int firstNumber, int secondNumber) {
        Operator operator = OperatorFactory.build(typeOfOperator);
        int result = operator.call(firstNumber, secondNumber);
        System.out.println("result = " + result);
    }
}

class OperatorFactory {
    static Operator build(String type) {
        Operator res;
        type = type.trim();
        switch (type) {
            case "add":
                res = new Add();
                break;
            case "subtract":
                res = new Subtract();
                break;
            case "multiply":
                res = new Multiply();
                break;
            case "divide":
                res = new Divide();
                break;
            default:
                throw new IllegalArgumentException(type);
        }
        return res;
    }
}


interface Operator {
    int call(int first, int second);
}

class Add implements Operator {
    @Override
    public int call(int first, int second) {
        return first + second;
    }
}

class Subtract implements Operator {
    @Override
    public int call(int first, int second) {
        return first - second;
    }
}

class Multiply implements Operator {
    @Override
    public int call(int first, int second) {
        return first * second;
    }
}

class Divide implements Operator {
    @Override
    public int call(int first, int second) {
        return first / second;
    }
}

两条评论:

  • 至于&#34;紧凑性&#34;:编写代码应该简洁,即意味着代码越短越好!
    代码首先应该是可读的和可维护的。

  • 由于运算符是作为字符串传递的 - 因此无法根据类型重载方法来执行不同的操作。一个答案建议反思:虽然这是唯一的&#34; compact&#34;我可以考虑的方式 - 考虑到以下因素,这也是一个糟糕的选择:

    1. 调试性
    2. 可维护性
    3. 代码性能(反射在运行时完成,这使得它比其替代方案慢得多)

答案 2 :(得分:1)

所以你调用了$validator = Validator::make($request->all(), [ 'article_title.*' => 'required', ]);方法,但是你没有从中调用方法。您需要确定operator值是什么,然后您应该调用与之关联的相应方法。例如,

typeofOperator

正如其他人提到的那样,您需要更改这些方法以反映您所暗示的操作类型(public static void operator( String typeofOperator, int firstNumber, int secondNumber){ if( typeofOperator.equals("+") ) { add(firstNumber, secondNumber); } else if( typeofOperator.equals("-") ) { subtract(firstNumber, secondNumber); } else if( typeofOperator.equals("*") ) { multiply(firstNumber, secondNumber); } else if( typeofOperator.equals("/") ) { divide(firstNumber, secondNumber); } else throw new IllegalArgumentException(); //If we get here, we didn't get a valid argument. } 应该添加两个数字,add应该减去这两个数字等。)< / p>

答案 3 :(得分:0)

您无法将Strings称为方法。您必须使用if或switch-case语句。

switch (typeOfOperator) {

case "add":
add(firstNumber, secondNumber); break;

case "subtract":
subtract(firstNumber, secondNumber); break;

case "multiply":
multiply(firstNumber, secondNumber); break;

case "divide":
divide(firstNumber, secondNumber); break;

}

答案 4 :(得分:0)

我建议创建一个HashMap,将实际运算符存储为键,将方法名称存储为值,以便您可以使用它来访问要根据类型调用的特定方法由用户输入的操作员。然后,您可以使用反射通过包含方法名称的字符串调用方法。

首先,在主要方法中制作HashMap<String, String> operators = new HashMap<String, String>(); operators.put("+", "add"); operators.put("-", "subtract"); operators.put("*", "multiply"); operators.put("/", "divide");

String chosenOperator = operators.get(typeOfOperator); //retrieves the method name
methods m = new methods(); //reflection
Method method = m.class.getMethod(chosenOperator);
method.invoke(m, firstNumber, secondNumber); //parameters are the object and
                                             //the method's parameters

然后,取输入的运算符从hashmap中获取正确的方法名称,并使用main方法中的反射调用方法,

HashMap

编辑:您可以使用命令模式将方法保存为对象,并将其插入HashMap<String, Runnable> operators = new HashMap<String, Runnable>(); Runnable addMethod = () -> add(firstNumber, secondNumber); Runnable subtractMethod = () -> subtract(firstNumber, secondNumber); Runnable multiplyMethod = () -> multiply(firstNumber, secondNumber); Runnable divideMethod = () -> divide(firstNumber, secondNumber); operators.put("+", addMethod); operators.put("-", subtractMethod); operators.put("*", multiplyMethod); operators.put("/", divideMethod); operators.get(typeOfOperator).run(); 而不是方法的名称,而不是使用反射。

这是使用lambdas的 Java 8 解决方案,

HashMap<String, Runnable> operators = new HashMap<String, Runnable>();
operators.put("+", () -> add(firstNumber, secondNumber));
operators.put("-", () -> subtract(firstNumber, secondNumber));
operators.put("*", () -> multiply(firstNumber, secondNumber));
operators.put("/", () -> divide(firstNumber, secondNumber));
operators.get(typeOfOperator).run();

顺便说一句,你可以这样做,以缩短它,

Runnable

但我想表明正在使用{{1}}类型的对象。

答案 5 :(得分:0)

这可以是if / else和switch方法的替代解决方案。 请注意,result()方法已从每个方法中移开。

import java.util.Scanner;

public class methods {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Welcome, choose your operator, would you like to add, subtract, multiply, or divide?");
        String typeofOperator = sc.nextLine();
        System.out.print("Enter the first number: ");
        int firstNumber = sc.nextInt();
        System.out.print("Enter the second number: ");
        int secondNumber = sc.nextInt();
        operator(typeofOperator, firstNumber, secondNumber);
    }

    public static void operator(String typeofOperator, int firstNumber, int secondNumber) {
        java.lang.reflect.Method method;
        Object returnedValue = null;
        try {
            method = methods.class.getDeclaredMethod(typeofOperator, int.class, int.class);
            returnedValue = method.invoke(null, firstNumber, secondNumber);
        } catch (Exception e) {
            e.printStackTrace();
        }
        result((Integer) returnedValue);
    }

    public static int add(int firstNumber, int secondNumber) {
        int answer = firstNumber + secondNumber;
        return answer;
    }
    public static int subtract(int firstNumber, int secondNumber) {
        int answer = firstNumber - secondNumber;
        return answer;
    }
    public static int multiply(int firstNumber, int secondNumber) {
        int answer = firstNumber * secondNumber;
        return answer;
    }
    public static int divide(int firstNumber, int secondNumber) {
        int answer = firstNumber / secondNumber;
        return answer;
    }
    public static void result(int result) {
        System.out.println("This is the result: " + result);
    }
}