Альтернатива операторов if-else и switch
У меня есть следующий код в Java:
public void doSomething(int i) {
if (i == 12) {
// order should be same
up();
left();
stop();
}
if (i == 304) {
// order should be same
right();
up();
stop();
}
if (i == 962) {
// order should be same
down();
left();
up();
stop();
}
}
// similar code can be done using switch case statements.
// all the function can have any functionality and might not resemble to the name given to them.
Теперь, если меня попросят не использовать аргументы if-else и switch case, то что можно сделать? Код может быть выполнен в Java или JavaScript.
Ответы
Ответ 1
Если вы можете использовать JavaScript, вы можете использовать объект с функциями:
function doSomething(i) {
var obj = {};
obj[12] = function () {
// order should be same
up();
left();
stop();
};
obj[304] = function () {
// order should be same
right();
up();
stop();
};
obj[962] = function () {
// order should be same
down();
left();
up();
stop();
};
// apparently we can't use any conditional statements
try {
obj[i]();
} catch (e) {}
}
Если не разрешены только операторы if
и switch
, замените все операторы if
логическим оператором AND (&&
):
function doSomething(i) {
(i == 12) && (
// order should be same
up(),
left(),
stop()
);
(i == 304) && (
// order should be same
right(),
up(),
stop()
);
(i == 962) && (
// order should be same
down(),
left(),
up(),
stop()
);
}
Ответ 2
Вот простой способ выполнить это в JavaScript:
function up() { console.log("up"); }
function down() { console.log("down"); }
function left() { console.log("left"); }
function right() { console.log("right"); }
function stop() { console.log("stop"); }
var fnmaps = {
12: [up, left, stop],
304: [right, up, stop],
962: [down, left, up, stop]
};
function doSomething(i) {
var fnmap = fnmaps[i] || [], j;
for (j = 0; j < fnmap.length; j++) {
fnmap[j]();
}
}
doSomething(12);
doSomething(304);
doSomething(962);
Функции могут быть добавлены/упорядочены просто путем редактирования переменной карты.
Ответ 3
Вы можете сделать словарь ввода-вывода. В Java это будет Map<Integer, Runnable>
, с, например: *:
map.put(12, () -> {
up();
left();
stop();
});
Затем вы можете получить соответствующий Runnable
и запустить его:
Runnable action = map.get(i);
if (action != null) {
action.run();
} else {
// some default action
// This is the "default" case in a switch, or the "else" in an if-else
}
В противном случае нет необходимости, но без него вы получите NullPointerException
, если i
не является ожидаемым значением — то есть одно из значений, которые вы помещаете в карту.
Идея похожа на JavaScript, но с объектами вместо Map
s, функциями (возможно, анонимными) вместо Runnable
s и т.д.
Этот код предназначен для Java 8. В Java 7 и ниже вы должны:
map.put(12, new Runnable() {
@Override
public void run() {
up();
left();
stop();
}
});
суб >
Ответ 4
Вахахахахаха, ты спас мой день:) Это должно сработать, теперь нет возможности проверить.
public void doSomething(int i) {
try {
int x = 1/(12-i); // fails for i==12
} catch (ArithmeticException e) {
up();
left();
stop();
}
и т.д., наслаждайтесь!
Ответ 5
Затем сделайте это с while и break, нет другого способа без проверки условий
public void doSomething(int i) {
while(i == 12) {
// order should be same
up();
left();
stop();
break;
}
while(i == 304) {
// order should be same
right();
up();
stop();
break;
}
while(i == 962) {
// order should be same
down();
left();
up();
stop();
break;
}
}
Ответ 6
Посмотрите, естественно, вы должны проверить условный оператор с условным выражением!
Теперь, если вы не хотите этого делать, вы можете сделать это неестественно:
сначала сделайте это для всех методов (вверх, вниз,...)
java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
вместо целого числа, которое вы передаете в doSomething
, используйте массив, содержащий имя методов, которые вы хотите вызвать, и внутри цикла for вызовите каждый метод следующим образом:
Затем вы вызываете этот метод, вызывая
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
К сожалению, Java не имеет делегатов!
Ответ 7
для js u может попробовать следующее:
// define ur actions here
var actions = {
"12" : function () { up(); left(); stop(); },
"304" : function () { right(); up(); stop(); },
"962" : function () { down(); left(); up(); stop(); }
};
function doSomething(i) {
var fn = actions[i];
try {
fn();
} catch (err) {
console.error(err);
}
}
//
doSomething(12); //invoke here
Ответ 8
Эта проблема может быть решена с использованием методов ООП.
В java это будет выглядеть так:
public abstract class AObject{
public abstract void doSomething();
public void up(){
//do something here
}
public void down(){
//do something here
}
public void left(){
//do something here
}
public void right(){
//do something here
}
public void stop(){
//do something here
}
}
public class AObject12 extends AObject{
public void doSomething(){
up();
left();
stop();
}
}
public class AObject304 extends AObject{
public void doSomething(){
right();
up();
stop();
}
}
public class AObject962 extends AObject{
public void doSomething(){
down();
left();
up();
stop();
}
}
Выполнение doSomething на экземпляре конкретного класса вызовет соответствующее поведение. Поэтому больше нет, если /else необходимо. Смотрите пример ниже:
AObject A12 = new AObject12();
A12.doSomething();
// Will run Up left stop in that order
AObject A304 = new AObject304();
A304.doSomething();
// Will run right Up stop in that order
AObject A962 = new AObject962();
A962.doSomething();
// Will run down left up stop in that order
Дополнительную информацию об этом виде программирования можно найти здесь: http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29
Если вы хотите динамически изменять поведение объекта, вы можете рассмотреть возможность применения шаблона состояния: http://en.wikipedia.org/wiki/State_pattern p >
Ответ 9
В Java это должно работать.
public class IfTest {
public static void main(String[] args) {
IfTest ifTest = new IfTest();
ifTest.doSomething(12);
ifTest.doSomeThingWithoutIf(12);
ifTest.doSomething(304);
ifTest.doSomeThingWithoutIf(304);
ifTest.doSomething(962);
ifTest.doSomeThingWithoutIf(962);
ifTest.doSomething(42);
ifTest.doSomeThingWithoutIf(42);
}
public void doSomeThingWithoutIf(int i) {
boolean x = i == 12 ? f12() : (i == 304 ? f304() : (i == 962 ? f962() : false));
}
public boolean f12() {
up();
left();
stop();
return true;
}
public boolean f304() {
right();
up();
stop();
return true;
}
public boolean f962() {
down();
left();
up();
stop();
return true;
}
public void doSomething(int i) {
if(i == 12) {
// order should be same
up();
left();
stop();
}
if(i == 304) {
// order should be same
right();
up();
stop();
}
if(i == 962) {
// order should be same
down();
left();
up();
stop();
}
}
private boolean retfalse() {
return false;
}
private void down() {
System.out.println("down");
}
private void right() {
System.out.println("right");
}
private void stop() {
System.out.println("stop");
}
private void left() {
System.out.println("left");
}
private void up() {
System.out.println("up");
}
}
Ответ 10
Желаемое поведение может быть достигнуто в JAVA, играя с коротким замыканием логического оператора AND следующим образом:
public static Boolean seq12() {
// order should be same
up();
left();
stop();
return true;
}
public static Boolean seq304() {
// order should be same
right();
up();
stop();
return true;
}
public static Boolean seq962() {
// order should be same
down();
left();
up();
stop();
return true;
}
public static void doSomething(int i) {
Boolean tmp;
tmp = (i == 12 && seq12());
tmp = (i == 304 && seq304());
tmp = (i == 962 && seq962());
}
Этот код довольно прямолинейный и полагается на тот факт, что логический оператор AND оценивает только второй операнд, если первый имеет значение true.