2017-01-05 2 views
1

나는 선택의 여지가있는 연산자와 두 개의 다른 숫자를 사용자에게 물어보고 결과를 출력하는 연습을하고 있습니다. 나는 다른 사람이나 스위치 케이스로이 운동을 쉽게 할 수 있지만, 실제로는이 방법으로 작동시키고 싶습니다. 문제는 내 연산자 메서드에서, 분명히 자바에서 매개 변수를 전달하고 메서드를 호출하려면 해당 매개 변수를 사용할 수 없습니다. 이 일을 할 수있는 방법이 있습니까? 당신이 질문에 혼란 스러웠다면 분명히 밝혀 줄 것입니다.Java 8에서 매개 변수를 사용하여 메소드를 호출하는 방법은 무엇입니까?

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); 
    } 
} 
+1

이되지 관련,하지만 난 빼기, 곱하기와 나누기 모두 사용하여 구현하고 있다는 사실은'+'아마 실수라고 생각 ... – alfasin

+0

이는 HTTP를 도울 수있다 : // 유래.com/questions/160970/how-do-i-invoke-a-java-method-when-given-the-method-name-as-a-string –

답변

1

그래서 당신은 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. 
} 

으로, 당신은 당신이 암시하는 작업의 유형 (addsubtract는 등 두 숫자를 빼는한다, 두 숫자를 추가해야합니다) 반영하기 위해 이러한 방법을 변경해야합니다.

+0

@Orin을 말하는 것이지만 if/else 또는 switch/case를 사용하지 않고이 작업을 수행 할 수있는 방법이 있는지 확인하려고합니다. 대신 나는 사용자 입력을 받아 들여 그 같은 입력을 사용하여 (올바르게 답변을 입력했다고 가정) 매개 변수 "typeofOperator"를 사용하여 함수를 호출하려고합니다. –

+0

@RubenVarela 그러면 Chris Gong이 아래에 제안한대로 Reflection 또는 메서드 참조를 사용하려고 할 것입니다. – Orin

0

문자열을 메서드로 호출 할 수 없습니다. 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; 

} 
0
난 당신이 연산자의 종류에 따라 호출 할 특정 방법에 액세스하는 데 사용할 수 있도록 값으로 키와 메소드 이름으로 실제 운영자를 저장하는 HashMap을 만드는 게 좋을 것

사용자에 의해 입력된다. 그런 다음 리플렉션을 사용하여 메소드 이름을 포함하는 문자열로 메소드를 호출 할 수 있습니다.

다음
HashMap<String, String> operators = new HashMap<String, String>(); 
operators.put("+", "add"); 
operators.put("-", "subtract"); 
operators.put("*", "multiply"); 
operators.put("/", "divide"); 

는, 해시 맵에서 올바른 메소드 이름을 얻을 주요 방법에 반사를 사용하여 메서드를 호출 할 입력 된 조작을

먼저, 메인 메소드에서 HashMap을,

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 

EDIT : 리플렉션을 사용하는 대신 명령 패턴을 사용하여 메서드를 개체로 잡고 이름이 o가 아닌 HashMap에 삽입 할 수 있습니다. 메소드.

길함으로써 자바 8 솔루션을 사용하여 람다,

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(); 

, 당신은 짧게하기 위해이 작업을 수행 할 수

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이 사용되었습니다.

+2

왜 반사입니까? 이것은없이 할 수 있습니다. 그렇지 않으면 좋은 대답입니다. –

+0

@ John Vernee 아마도 그렇 겠지만 if/else if 문을 사용하지 않고 그냥 사용하는 방법입니다. –

+0

예, 여전히 hashmap을 사용할 수 있지만 리플렉션은 런타임에 메소드를 검색해야합니다. functor (자바 8'methods :: add','methods :: multiply' 및'IntBinaryOperator')에서 함수를 래핑하고 맵에 추가 할 수 있습니다. 그 방법은 컴파일 타임에 해결할 수 있습니다. –

2

자바 당신은/다른과에 기반 호출해야하는 방법을 알아낼 경우에 당신이 일을 시작할 수 있습니다, 매개 변수를 전달하고 방법

자에게 전화를이 매개 변수를 사용할 수 없습니다 연산자 유형.각 작업마다 하나 :

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; 
    } 
} 
를 구현하는 클래스를 생성 한 후

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

과 :

우리는 Operator 인터페이스를 정의 할 수 있습니다 : 그것은 청소기가 될 객체 지향 접근 방식 같은 느낌 말했다

이제는 operator-type을 인수로 사용하고 관련 연산자 객체를 각각 생성하는 팩토리가 필요합니다. 한 가지 방법은 다음과 같습니다

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

두 의견 : "컴팩트"에 관해서는

  • :

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

    가의 코드가 어떻게 작동하는지 살펴 보자 코드를해야 작성 참으로 간결하게 말하자면, 그것은 이 아니기 때문에은 코드가 짧다는 것을 의미합니다.
    코드는 가장 먼저 읽고 유지할 수 있어야합니다.

  • 연산자는 문자열로 전달되므로 형식에 따라 다른 작업을 수행하는 메서드를 오버로드 할 수 없습니다. 하나의 대답은 반사를 제안 : - : (반사에서 수행됩니다

    1. debuggability
    2. 유지 보수
    3. 코드 성능이 내가 생각 할 수있는 유일한 "소형"방법이있는 동안은 또한 다음을 고려 나쁜 선택이다 그 대안보다 훨씬 느린하게 실행) 기능을
5

사용지도. 그것은 자바 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); 
    } 
} 

물론 사용자가 존재하지 않는 연산자를 지정할 수 있는지 확인하지 않습니다.

업데이트 : 코드를 컴파일 할 수 있도록 모든 연산자 메소드에 "return 0"을 추가했습니다. 필요한 기능을 수행하는 방법을 지정하기 위해 원본 코드를 최소한으로 변경하려고했습니다.

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)); 
    } 
} 
+0

코드가 컴파일되지 않습니다 ... – alfasin

+0

물론 그렇지 않습니다. 각 연산자의 메소드에 return 문을 추가해야합니다. 필자는 원래 코드에 최소한의 변경 만 추가하려고했습니다. –

+0

:))) 왜 "무효"로 선언하지 않습니까? btw, 나는 너의 대답을 좋아한다! – alfasin

0

이 경우는/다른 사람과 스위치 방법에 대한 대안 솔루션이 될 수 있습니다 : 운영자 방법이 필요하지 않은 경우, 나는 그것을 간단하게 작성하고 싶습니다. 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); 
    } 
} 
관련 문제