Java Enum Methods-return opposite direction enum

Chciałbym zadeklarować kierunek enum, który ma metodę, która zwraca przeciwny kierunek (poniższy nie jest poprawny składniowo, tzn. nie można utworzyć instancji enum, ale ilustruje to mój punkt widzenia). Czy jest to możliwe w Javie?

Oto kod:

public enum Direction {

     NORTH(1),
     SOUTH(-1),
     EAST(-2),
     WEST(2);

     Direction(int code){
          this.code=code;
     }
     protected int code;
     public int getCode() {
           return this.code;
     }
     static Direction getOppositeDirection(Direction d){
           return new Direction(d.getCode() * -1);
     }
}
Author: Pshemo, 2013-09-18

6 answers

Dla zwabionych tutaj tytułem: Tak, możesz zdefiniować własne metody w swoim enum. Jeśli zastanawiasz się, jak wywołać taką niestatyczną metodę, robisz to tak samo jak w przypadku każdej innej niestatycznej metody-wywołujesz ją na instancji typu, która definiuje lub dziedziczy tę metodę. W przypadku enum są to po prostu ENUM_CONSTANT s.

Więc wszystko czego potrzebujesz to EnumType.ENUM_CONSTANT.methodName(arguments).


Teraz wróćmy do problemu z pytania. Jednym z rozwiązań może być

public enum Direction {

    NORTH, SOUTH, EAST, WEST;

    private Direction opposite;

    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        EAST.opposite = WEST;
        WEST.opposite = EAST;
    }

    public Direction getOppositeDirection() {
        return opposite;
    }

}

Teraz Direction.NORTH.getOppositeDirection() powróci Direction.SOUTH.


Tutaj jest trochę bardziej "hakerski" sposób na zilustrowanie @jedwards comment ale nie wydaje się tak elastyczny jak pierwsze podejście, ponieważ dodanie większej liczby pól lub zmiana ich kolejności złamie nasz kod.

public enum Direction {
    NORTH, EAST, SOUTH, WEST;

    // cached values to avoid recreating such array each time method is called
    private static final Direction[] VALUES = values();

    public Direction getOppositeDirection() {
        return VALUES[(ordinal() + 2) % 4]; 
    }
}
 210
Author: Pshemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-21 15:21:45

Dla takiego małego wyliczenia uważam za najbardziej czytelne rozwiązanie:

public enum Direction {

    NORTH {
        @Override
        public Direction getOppositeDirection() {
            return SOUTH;
        }
    }, 
    SOUTH {
        @Override
        public Direction getOppositeDirection() {
            return NORTH;
        }
    },
    EAST {
        @Override
        public Direction getOppositeDirection() {
            return WEST;
        }
    },
    WEST {
        @Override
        public Direction getOppositeDirection() {
            return EAST;
        }
    };


    public abstract Direction getOppositeDirection();

}
 163
Author: Amir Afghani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-18 23:06:24

To działa:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction oppose() {
        switch(this) {
            case NORTH: return SOUTH;
            case SOUTH: return NORTH;
            case EAST:  return WEST;
            case WEST:  return EAST;
        }
        throw new RuntimeException("Case not implemented");
    }
}
 28
Author: Pikrass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 10:35:17

Utwórz abstrakcyjną metodę i niech każda z wartości wyliczania nadpisuje ją. Ponieważ podczas tworzenia znasz coś przeciwnego, nie ma potrzeby dynamicznego generowania lub tworzenia go.

Nie czyta się jednak ładnie; być może switch byłoby łatwiejsze do opanowania?

public enum Direction {
    NORTH(1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.SOUTH;
        }
    },
    SOUTH(-1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.NORTH;
        }
    },
    EAST(-2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.WEST;
        }
    },
    WEST(2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.EAST;
        }
    };

    Direction(int code){
        this.code=code;
    }
    protected int code;

    public int getCode() {
        return this.code;
    }

    public abstract Direction getOppositeDirection();
}
 14
Author: Makoto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-18 23:04:11

Tak, robimy to cały czas. Zwracasz statyczną instancję zamiast nowego obiektu

 static Direction getOppositeDirection(Direction d){
       Direction result = null;
       if (d != null){
           int newCode = -d.getCode();
           for (Direction direction : Direction.values()){
               if (d.getCode() == newCode){
                   result = direction;
               }
           }
       }
       return result;
 }
 4
Author: BevynQ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-09 21:33:04
public enum Direction {
    NORTH, EAST, SOUTH, WEST;

    public Direction getOppositeDirection(){
        return Direction.values()[(this.ordinal() + 2) % 4];
    }
}

Enums posiada metodę statycznych wartości, która zwraca tablicę zawierającą wszystkie wartości enum w kolejności, w jakiej są zadeklarowane. Źródło

Ponieważ północ dostaje 1, Wschód dostaje 2, południe dostaje 3, zachód dostaje 4; można utworzyć proste równanie, aby otrzymać przeciwne:

(wartość + 2) % 4

 0
Author: Pregunton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-27 21:33:12