web-dev-qa-db-fra.com

Java Méthodes Enum

Je voudrais déclarer une direction enum, qui a une méthode qui retourne la direction opposée (ce qui suit n’est pas syntaxiquement correct, c’est-à-dire que les énumérations ne peuvent pas être instanciées, mais elles illustrent mon propos). Est-ce possible en Java?

Voici le code:

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);
     }
}
101
Skyler

Pour ceux attirés ici par titre: oui, vous pouvez définir vos propres méthodes en enum. Si vous vous demandez comment appeler une telle méthode non statique, vous procédez de la même manière que pour toute autre méthode non statique: vous l'invoquez sur une instance de type qui définit ou hérite de cette méthode. Dans le cas d'enum, ces instances sont simplement ENUM_CONSTANTs.

Donc, tout ce dont vous avez besoin est EnumType.ENUM_CONSTANT.methodName(arguments).


Revenons maintenant au problème de la question. Une des solutions pourrait être

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;
    }

}

Maintenant, Direction.NORTH.getOppositeDirection() retournera Direction.SOUTH.


Voici un peu plus "hacky" moyen d'illustrer @ jedwards comment mais il n'est pas aussi souple que la première approche car ajouter plus de champs ou changer leur ordre cassera notre code.

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]; 
    }
}
189
Pshemo

Pour une petite énumération comme celle-ci, je trouve la solution la plus lisible:

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();

}
148
Amir Afghani

Cela marche:

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");
    }
}
22
Pikrass

Créez une méthode abstraite et faites-la remplacer par chacune de vos valeurs d'énumération. Comme vous savez le contraire lorsque vous le créez, il n'est pas nécessaire de le générer ou de le créer dynamiquement.

Il ne lit pas bien cependant; peut-être qu'un switch serait plus facile à gérer?

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
Makoto

Oui nous le faisons tout le temps. Vous retournez une instance statique plutôt qu'un nouvel objet

 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;
 }
5
BevynQ
public enum Direction {
    NORTH, EAST, SOUTH, WEST;

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

Les énumérations ont une méthode de valeurs statiques qui renvoie un tableau contenant toutes les valeurs de l’énum dans leur ordre de déclaration. source

depuis que NORT a 1, EST en a 2, SUD en a 3, OUEST en 4; vous pouvez créer une équation simple pour obtenir l'inverse:

(valeur + 2)% 4

0
Pregunton