Объектно-ориентированный способ сделать это - использовать перечисление возможных операций. Таким образом, каждая операция может использовать только один объект в памяти.
public enum Operation {
ADD() {
public int perform(int a, int b) {
return a + b;
}
},
SUBTRACT() {
public int perform(int a, int b) {
return a - b;
}
},
MULTIPLY() {
public int perform(int a, int b) {
return a * b;
}
},
DIVIDE() {
public int perform(int a, int b) {
return a / b;
}
};
public abstract int perform(int a, int b);
}
Чтобы вызвать такой код, вы должны сделать что-то вроде:
int result = Operation.ADD(5, 6);
Тогда вы можете создать карту Строк для Операций, например так:
Map<String, Operation> symbols = new Map<String, Operation>();
symbols.put("+", Operation.ADD);
symbols.put("-", Operation.SUBTRACT);
symbols.put("/", Operation.DIVIDE);
symbols.put("*", Operation.MULTIPLY);
...
Наконец, для использования такой системы:
symbols.get(n.getString(1).apply(tmp1, tmp2));
Одним из преимуществ использования перечислений таким образом является то, что у вас есть возможность сравнивать операции с данными, если вы решите это сделать
Operation operation = symbols.get("*");
if (operation != Operation.MULTIPLY) {
System.out.println("Foobar as usual, * is not multiply!");
}
Кроме того, вы получаете централизованное расположение для всех операций, единственным недостатком которого является то, что файл Operation.java может стать большим с достаточно большим набором операторов.
Единственные проблемы, которые могут существовать в долгосрочной перспективе, это то, что, хотя такая система полезна и проста для чтения и понимания, она действительно не учитывает приоритет. Предполагая, что ваша формула оценивается в порядке приоритета, такая проблема не имеет значения. Примеры выражения формулы в порядке приоритета можно найти в обратной польской записи, польской записи и т. Д.
Приоритет имеет значение, когда вам разрешено выражать такие предметы, как:
4 + 5 * 2
, где в соответствии с типичным соглашением, 5 * 2 следует оценивать до 4 + 5. Единственный правильный способ обработки приоритета - это создать дерево оценки в памяти или гарантировать, что все входные данные обрабатывают приоритет в простом, однозначная манера (польская запись, обратная польская запись и т. д.).
Я предполагаю, что вы знаете о проблемах предшествования, но спасибо, что позволили мне упомянуть об этом для тех, кому еще не приходилось писать такой код.