Illegal Forward Reference and Enums

前端 未结 11 1421
-上瘾入骨i
-上瘾入骨i 2020-12-08 09:46

I\'m programming a game in java which is made up of a grid of tiles. I wan\'t to be able to inuitively define the edges of the tiles and how they relate to each other, e.g.

相关标签:
11条回答
  • 2020-12-08 09:53
    public enum Edge {
    
        TOP,
        BOTTOM(Edge.TOP),
        LEFT,
        RIGHT(Edge.LEFT);
    
        private Edge opposite;
    
        private Edge() {
    
        }
        private Edge(Edge opp) {
            this.opposite = opp;
            opp.opposite = this;
        }
    
        public Edge opposite() {
            return this.opposite;
        }
    }
    
    0 讨论(0)
  • 2020-12-08 09:55

    You can do this which is not as intuitive.

    public enum Edge {
        TOP, BOTTOM, LEFT, RIGHT;
        private Edge opposite;
    
        static {
            TOP.opposite = BOTTOM;
            BOTTOM.opposite = TOP;
            LEFT.opposite = RIGHT;
            RIGHT.opposite = LEFT;
        }
        public Edge opposite(){
            return this.opposite;
        }
    }
    
    0 讨论(0)
  • 2020-12-08 09:57

    Here's another way

    public enum Edge {
    
        TOP("BOTTOM"),
        BOTTOM("TOP"),
        LEFT("RIGHT"),
        RIGHT("LEFT");
    
        private String opposite;
    
        private Edge(String opposite){
            this.opposite = opposite;
        }
    
        public Edge opposite(){
            return valueOf(opposite);
        }
    
    }
    

    Peter Lawrey's solution is however more efficient and compiletime safe.

    0 讨论(0)
  • 2020-12-08 09:58

    I preferred this:

    public enum Edge {
       TOP,
       BOTTOM,
       LEFT,
       RIGHT;
    
       private Link link;
    
       private Link getLink() {
         if (link == null) {
            link = Link.valueOf(name());
         }
         return link;
       }
    
       public Edge opposite() {
          return getLink().opposite();
       }
    }
    
    public enum Link {
       TOP(Edge.BOTTOM),
       BOTTOM(Edge.TOP),
       LEFT(Edge.RIGHT),
       RIGHT(Edge.LEFT);
    
       private Edge opposite;
    
       private Link(Edge opp) {
          this.opposite = opp;
       }
    
       public Edge opposite() {
          return this.opposite;
       }
    }
    
    0 讨论(0)
  • 2020-12-08 10:03

    You can create a static Map where key is the original enum and the value the opposite edge. Initialize it in a static block and the return the mapping from the opposite() method.

    private static Map<Edge, Edge> oppostiteMapping;
    
    static {
      oppositeMapping = new EnumMap<Edge, Edge>();
      oppositeMapping.put(TOP, BOTTOM);
      ...
    }
    
    public Edge opposite() {
        return oppositeMapping.get(this);
    } 
    

    EDIT: as proposed in comment better to use EnumMap, so I upgraded accordingly

    Btw. this approach is generally useful when you create something like static fromString() method etc.

    0 讨论(0)
  • 2020-12-08 10:04

    With Java 8 lambdas:

    public enum Edge {
      TOP(() -> Edge.BOTTOM),
      BOTTOM(() -> Edge.TOP),
      LEFT(() -> Edge.RIGHT),
      RIGHT(() -> Edge.LEFT);
    
      private Supplier<Edge> opposite;
    
      private Edge(Supplier<Edge> opposite) {
        this.opposite = opposite;
      }
    
      public Edge opposite() {
        return opposite.get();
      }
    }
    
    0 讨论(0)
提交回复
热议问题