表达此 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 truefalse 也很简单,具体取决于它调用的是 m() 还是 ynull .


你也可以用循环结构做一些技巧,虽然有些人可能会说这是对循环结构的滥用,你应该相应地评论它:

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 为空可能更好,但我假设您想在调用方进行此检查。