java - 在具有两个实例变量的对象上切换大小写

标签 java

Java 中是否可以使用对象而不是基本类型来进行 switch-case 语句?

我有一个场景,其中有很多 2d 位置 (x,y),我希望每个位置在触发后都有不同的行为。

例如,我想:

Pos pos = getNextPos();

switch (pos) {
    case new Pos(1, 2):
        // do something
        break;
    case new Pos(9, 7):
        // do something else...
        break;
    etc...
}

或者也许

Pos pos = getNextPos();
Pos[] listOfPos = getListOfPos();

switch (pos) {
    case listOfPos[0]:
        // do something
        break;
    case listOfPos[1]:
        // do something else...
        break;
    etc...
}
<小时/>

我还在我的 Pos 类中实现了 .equals() 方法,仅当 x 和 y 都等于另一个对象时才返回 true。

Pos 类(带有自动生成的 equals 和 hashCode):

public class Pos {
    public int x;
    public int y;

    public Pos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Pos pos = (Pos) o;
        return x == pos.x && y == pos.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

我已经尝试了所有这些,但在编译时我得到“不兼容的类型:Pos 无法转换为 int”。

最佳答案

使用 Java 8 和 lambda,您可以找到无需 switch 的方法:

class Foobar {
  private final Map<Pos, Consumer<Pos>> mapping;

  Foobar() {
    mapping = new HashMap<>();
    mapping.put(new Pos(1, 2), this::doSomething1);
    mapping.put(new Pos(5, 2), this::doSomething2);
  }

  private void doSomething1(Pos pos) { ... }
  private void doSomething2(Pos pos) { ... }

  public void handleNextPost() {
    Pos pos = getNextPos();
    Consumer<Pos> consumer = mapping.get(getNextPos());
    if (null != consumer) {
      consumer.accept(pos);
    }
  } 
}

顺便说一句,在字节码级别,String 上的 switch 几乎与 HashMap 相同:一个 tableswitch 使用 hashCode(),然后根据需要使用 goto 转到下一条语句。

上面的代码很简单:

  • 我声明一个 map,其中包含每个 Pos 您想要执行的操作。
  • 每个操作都是通过采用 Pos 的方法实现的
  • 当您阅读 getNextPos() 时,您会搜索处理所述位置的 Consumer
  • 使用nextPos调用Consumer

您可以在本地定义它,但必须确保不会每次都创建映射

如果您确实必须坚持使用 switch,则不需要任何特殊的东西:您正在使用 int 来表示 Pos x/yswitch 自然可以在 int 上工作:

switch (pos.getX()) {
  case 0: switch (pos.getY()) {
    case 1: { // [0, 1]
      break;
    }
    case 3: { // [0, 3]
       break;
    }     
  }
  break;
  // ... and so on
}

这很容易使您的代码难以阅读,因此请避免这样做。

此外,map 并不是为松散匹配而定制的(例如:对 x = 1 的每个 Pos 采取的操作),您可能必须使用其他替代方案。

关于java - 在具有两个实例变量的对象上切换大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59995065/

相关文章:

java - 如何更改打开对话框的图像以及如何在swing中自定义对话框?

java - ArrayList 中的索引越界异常

java - 我可以将 FlatfileItemReader 与 Taskexecutor 一起使用吗?

java - XSLT 应用特定值列表的模板

java - Libgdx map 更改

java - Spring Boot Security 不会抛出 401 Unauthorized Exception 但 404 Not Found

@Service 和@Autowired 注释的 Java/Spring 问题

java - 如何在 JAVA 中解析 JSONObjects 的 JSONArray?

java - Spring AbstractAnnotationConfigDispatcherServletInitializer 未找到 WebApplicationContext : no ContextLoaderListener registered

java - 从 C# 关闭 java 进程(在 Windows 上)