表达此 Java 条件的最简洁方式,无需检查值两次
Most concise way to express this Java conditional without checking a value twice
我有一个变量,x
。
我想调用方法 m()
仅当 x
是两个可能值之一时。
在调用m()
时,我想传递一个参数给它,其值取决于x
的值。
有没有一种方法可以在 Java 中执行此操作,而无需多次检查 x
的值,并且 calling/writing m()
仅在一个地方(即不在 if
语句的多个分支中)?
我正在接受的一个解决方案:
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
y = null;
break;
}
if (y != null) m(y);
但我不禁觉得这是 技术上 检查 x
两次,只是通过为第二次检查添加 "proxy" 来掩盖这一事实.
(澄清为什么约束是这样的:在阅读代码时,我很难理解当分支之间存在高度重复时分支很多的逻辑 - 它变成了 "spot the difference" 而不是简单地能够看到正在发生的事情。我更喜欢积极地重构这种重复,这是一个在 Ruby、JS 和其他语言中对我很有帮助的习惯;我希望我能学习为 Java 做同样的事情,让代码更容易让我和其他人一目了然。)
为什么不
switch (x) {
case 1:
y = "foo";
m(y);
break;
case 2:
y = "bar";
m(y);
break;
}
我不确定你想做什么,但你可以使用 Map 从 'x'
获取 'y' 参数
Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
if (map.containsKey(x)) {
m(map.get(x));
}
使用 "goto" 或等价物:
void do_m_if_appropriate() {
// x and y are assumed to be eg. member variables
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
return; // this is the "goto equivalent" part
}
m(y);
}
上面很优雅。如有必要,将其更改为 return true
或 false
也很简单,具体取决于它调用的是 m()
还是 y
或 null
.
你也可以用循环结构做一些技巧,虽然有些人可能会说这是对循环结构的滥用,你应该相应地评论它:
do { // note: not a real loop, used to skip call to m()
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
continue; // "goto equivalent" part
}
m(y);
} while(false);
这里有一个使用 Optionals 的解决方案(我的 Java 语法可能有点不正确)。请注意,代码看起来像这样,但在实现方面,它类似于您发布的示例(即检查 y 是否为异常值)。
switch (x) {
case 1:
y = Optional<String>.of("foo");
break;
case 2:
y = Optional<String>.of("bar");
break;
default:
y = Optional<String>.empty();
break;
}
y.map((m's class)::m);
result = y.orElse( <value result should take if x was invalid> );
实际上,将 m() 修改为 return 一个 Optional 并且如果 y 无效则 return 为空可能更好,但我假设您想在调用方进行此检查。
我有一个变量,x
。
我想调用方法 m()
仅当 x
是两个可能值之一时。
在调用m()
时,我想传递一个参数给它,其值取决于x
的值。
有没有一种方法可以在 Java 中执行此操作,而无需多次检查 x
的值,并且 calling/writing m()
仅在一个地方(即不在 if
语句的多个分支中)?
我正在接受的一个解决方案:
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
y = null;
break;
}
if (y != null) m(y);
但我不禁觉得这是 技术上 检查 x
两次,只是通过为第二次检查添加 "proxy" 来掩盖这一事实.
(澄清为什么约束是这样的:在阅读代码时,我很难理解当分支之间存在高度重复时分支很多的逻辑 - 它变成了 "spot the difference" 而不是简单地能够看到正在发生的事情。我更喜欢积极地重构这种重复,这是一个在 Ruby、JS 和其他语言中对我很有帮助的习惯;我希望我能学习为 Java 做同样的事情,让代码更容易让我和其他人一目了然。)
为什么不
switch (x) {
case 1:
y = "foo";
m(y);
break;
case 2:
y = "bar";
m(y);
break;
}
我不确定你想做什么,但你可以使用 Map 从 'x'
获取 'y' 参数Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
if (map.containsKey(x)) {
m(map.get(x));
}
使用 "goto" 或等价物:
void do_m_if_appropriate() {
// x and y are assumed to be eg. member variables
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
return; // this is the "goto equivalent" part
}
m(y);
}
上面很优雅。如有必要,将其更改为 return true
或 false
也很简单,具体取决于它调用的是 m()
还是 y
或 null
.
你也可以用循环结构做一些技巧,虽然有些人可能会说这是对循环结构的滥用,你应该相应地评论它:
do { // note: not a real loop, used to skip call to m()
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
continue; // "goto equivalent" part
}
m(y);
} while(false);
这里有一个使用 Optionals 的解决方案(我的 Java 语法可能有点不正确)。请注意,代码看起来像这样,但在实现方面,它类似于您发布的示例(即检查 y 是否为异常值)。
switch (x) {
case 1:
y = Optional<String>.of("foo");
break;
case 2:
y = Optional<String>.of("bar");
break;
default:
y = Optional<String>.empty();
break;
}
y.map((m's class)::m);
result = y.orElse( <value result should take if x was invalid> );
实际上,将 m() 修改为 return 一个 Optional 并且如果 y 无效则 return 为空可能更好,但我假设您想在调用方进行此检查。