1

My class implements a very simple prototype of an RPN calculator.

The following construct isn't working. Why? What am I doing wrong here?

public boolean executeCommand(String command) {
    if(command == "+")      { add();          return true; }else
    if(command == "-")      { subtrair();     return true; }else
    if(command == "*")      { multiplicar();  return true; }else
    if(command == "/")      { dividir();      return true; }else
        {
            System.out.println("The command does not exist.");
            return false;
        }
}

The output is always, no matter what the string contains,

The command does not exist.

Why? I really don't get it! If someone could please explain, I'd be thankful!


In more detail

The method in question is:

public boolean executeCommand(String command) {
    Scanner str = new Scanner(command);

    if (str.hasNextDouble()) {
        dataStack.push(str.nextDouble());
        return true;
    } else {

        System.out.format(" DEBUG: command: %s$%n", command);

        if(command == "+")      { add();          return true; }else
        if(command == "-")      { subtract();     return true; }else
        if(command == "*")      { multiply();     return true; }else
        if(command == "/")      { divide();       return true; }else
        if(command == ".")      { print();        return true; }else
        if(command == ".s")     { showStack();    return true; }else
        if(command == "exit")   { exit();         return true; }else
            {
                System.out.println("The command does not exist.");
                return false;
            }
    }
}

which, for any input I threw at it, (except for numbers, of course), resulted in:

 DEBUG: command: [COMMAND HERE]$
The command does not exist.

Source code

I removed some irrelevant source code; (i.e. some methods, package name) but it is still compilable and runnable:

import java.util.Scanner;
import java.util.LinkedList;

public class RPNCalculator {

    public static void main(String[] args) {
        RPNCalculator calc = new RPNCalculator();
        calc.startInteractiveMode();
    }

    protected Scanner scanInput;
    public LinkedList<Double> dataStack;
    protected boolean interactiveModeEnabled;

    public RPNCalculator() {
        scanInput = new Scanner(System.in).useDelimiter("\\s+");
        dataStack = new LinkedList<Double>();
    }

    public String getCommand() {
        return scanInput.next();
    }

    public boolean executeCommand(String command) {
        Scanner str = new Scanner(command);

        if (str.hasNextDouble()) {
            dataStack.push(str.nextDouble());
            return true;
        } else {

            System.out.format(" DEBUG: command: %s$%n", command);

            if(command == "+")   { ommitedOp("add");      return true; }else
            if(command == "-")   { ommitedOp("subtract"); return true; }else
            if(command == "*")   { ommitedOp("multiply"); return true; }else
            if(command == "/")   { ommitedOp("divide");   return true; }else
            if(command == ".")   { ommitedOp("print");    return true; }else
            if(command == ".s")  { ommitedOp("showStack");return true; }else
            if(command == "exit"){ ommitedOp("exit");     return true; }else
                {
                    System.out.println("The command does not exist.");
                    return false;
                }
        }
    }

    public void startInteractiveMode() {
        interactiveModeEnabled = true;

        while (interactiveModeEnabled) {
            String command = getCommand();
            executeCommand(command);
        }
    }

    public void ommitedOp(String method){
        System.out.println("Command exists!");
    }
}
g4v3
  • 133
  • 2
  • 10
  • @Tunaki Yes, I agree. This is mostly a duplicate. The only significant difference would be that this is a specific case instead of a general one: what I mean is that possibly (I don't know) this might be useful to someone else, as an example of the more general case, so I posted it anyway for future reference. – g4v3 Apr 27 '16 at 10:51

2 Answers2

1

...and I think I got it. Thanks, Stack Overflow's Similar Questions!

The problem was in how I tried to use the == operator, which only compares pointers and not Strings themselves: https://stackoverflow.com/a/10535836/3397179

In Java, you must use equals() for comparing equality between Strings. == tests for identity, a different concept.

Two objects can be equal but not identical; on the other hand if two objects are identical it's implied that they're equal.

Two objects are identical if they physically point to the same address in memory, whereas two objects are equal if they have the same value, as defined by the programmer in the equals() method. In general, you're more interested in finding out if two objects are equal.

— answered May 10 '12 at 14:11 by Óscar López

Now, let's just test this theory before posting, to avoid making a fool of myself and wasting others' time unnecessarily...... Confirmed.


Thus, the solution would be to use command.equals("COMMAND NAME") instead of command == "COMMAND NAME", like this:

public boolean executeCommand(String command) {
    if(command.equals("+"))      { add();          return true; }else
    if(command.equals("-"))      { subtrair();     return true; }else
    if(command.equals("*"))      { multiplicar();  return true; }else
    if(command.equals("/"))      { dividir();      return true; }else
        {
            System.out.println("The command does not exist.");
            return false;
        }
}
Community
  • 1
  • 1
g4v3
  • 133
  • 2
  • 10
1
command == "+"   // always checks for reference and it will be never same.

Instead use the below one

command.equals("=")
Maroun
  • 94,125
  • 30
  • 188
  • 241
Kulbhushan Singh
  • 627
  • 4
  • 20