Java Перечислять друг к другу Enum [дубликат]

def dbz():
    try:
        r = raw_input("Enter number:")
        if r.isdigit():
            i = int(raw_input("Enter divident:"))
            d = int(r)/i
            print "O/p is -:",d
        else:
            print "Not a number"
    except Exception ,e:
        print "Program halted incorrect data entered",type(e)
dbz()

Or 

num = input("Enter Number:")#"input" will accept only numbers
29
задан falsarella 19 August 2014 в 00:56
поделиться

5 ответов

Одним из лучших способов было бы использовать метод полиморфизма enum :

public class EnumTest {
    public enum Foo {
        A {

            @Override
            public Bar getBar() {
                return Bar.Alpha;
            }
        },
        B {

            @Override
            public Bar getBar() {
                return Bar.Delta;
            }
        },
        C {

            @Override
            public Bar getBar() {
                return Bar.Alpha;
            }
        },

        ;

        public abstract Bar getBar();
    }

    public enum Bar {
        Alpha {

            @Override
            public Foo getFoo() {
                return Foo.A;
            }
        },
        Beta {

            @Override
            public Foo getFoo() {
                return Foo.C;
            }
        },
        Delta {

            @Override
            public Foo getFoo() {
                return Foo.C;
            }
        },

        ;

        public abstract Foo getFoo();
    }

    public static void main(String[] args) {
        for (Foo f : Foo.values()) {
            System.out.println(f + " bar " + f.getBar());
        }
        for (Bar b : Bar.values()) {
            System.out.println(b + " foo " + b.getFoo());
        }
    }
}

Вышеприведенный код выводит желаемый результат:

A bar Alpha
B bar Delta
C bar Alpha
Alpha foo A
Beta foo C
Delta foo C

См. также:

21
ответ дан Community 22 August 2018 в 20:32
поделиться
  • 1
    Мне кажется, как осложнение. Ответ @ weiji намного чище, ИМО. Почему этот подход лучше (вы сказали «лучший»)? – Noam Nelke 19 May 2015 в 15:26
  • 2
    @NoamNelke Я уже голосовал за подход Weiji, что очень интересно. Несмотря на то, что я лично считаю, что это намного лучше, чем я рекомендовал, потому что циклическая ссылка находится в пределах перечисления, большая разница между нашими ответами заключается в том, что моя также позволит вам выполнить любую логику выполнения перед возвратом, как только это потребуется, например: public Bar getBar(boolean nullIfAlpha) { return nullIfAlpha ? null : Bar.Alpha; }. Во всяком случае, я отредактировал свой ответ на «один из лучших». вместо этого, поскольку это может быть основано на мнениях. Спасибо за ваш ответ! – falsarella 19 May 2015 в 17:29

Так как, похоже, вы все равно будете жестко кодироваться, почему бы не иметь что-то вроде

public static Bar responseBar(Foo f) {
 switch(f) {
  case A: return Bar.Alpha;
  // ... etc
 }
}

для каждого перечисления? Похоже, что у вас есть некоторые дублирующие ответы в вашем примере, так что вы даже можете воспользоваться случаями, которые проваливаются.

EDIT:

Мне нравится предложение Tom's EnumMap; I считает, что производительность , вероятно, выше на EnumMap, но такая элегантная конструкция, описанная в Effective Java, по-видимому, не предоставляется этой конкретной проблемой - однако предлагаемое выше решение коммутатора будет хорошим способ построить два статических EnumMaps, тогда ответ может быть примерно таким:

 public static Bar response(Foo f) { return FooToBar.get(f); }
 public static Foo response(Bar b) { return BarToFoo.get(b); }
3
ответ дан Carl 22 August 2018 в 20:32
поделиться
  • 1
    Или EnumMap, если вы предпочитаете это switch. – Tom Hawtin - tackline 1 October 2009 в 23:02
  • 2
    (Осторожно, как вы это понимаете, см. «Эффективная Java»). – Tom Hawtin - tackline 1 October 2009 в 23:03

Интересный дизайн. Я вижу вашу потребность, но что вы собираетесь делать, когда требования немного меняются, так что в ответ на Foo.Epsilon app_1 должен отправить либо Bar.Gamma или Bar.Whatsit?

Решение, которое вы рассмотрели и отбросило как хакерское (помещая отношение в карту), кажется, дает вам гораздо большую гибкость и позволяет избежать вашей циркулярной ссылки. Он также сохраняет ответственность разделенной: сами типы сообщений не должны нести ответственность за знание их ответа, не так ли?

1
ответ дан CPerkins 22 August 2018 в 20:32
поделиться

Проблема заключается не столько в том, что «две перечисления ссылаются друг на друга», это больше «два перечисления ссылаются друг на друга в своих конструкторах ». Эта круговая ссылка - сложная часть.

Как насчет использования методов Foo.setResponse(Bar b) и Bar.setResponse(Foo f)? Вместо того, чтобы устанавливать панель Foo в конструкторе Foo (и аналогично Bar's Foo в конструкторе Bar), вы выполняете инициализацию с помощью метода? Например:

Foo:

public enum Foo {
  A, B, C;

  private void setResponse(Bar b) {
    this.b = b;
  }

  private Bar b;

  public Bar getB() {
    return b;
  }

  static {
    A.setResponse(Bar.Alpha);
    B.setResponse(Bar.Delta);
    C.setResponse(Bar.Alpha);
  }
}

Bar:

public enum Bar {
  Alpha, Beta, Delta;

  private void setResponse(Foo f) {
    this.f = f;
  }

  private Foo f;

  public Foo getF() {
    return f;
  }

  static {
    Alpha.setResponse(Foo.A);
    Beta.setResponse(Foo.C);
    Delta.setResponse(Foo.C);
  }
}

Кроме того, вы отмечаете, что Foo и Bar - это два типа сообщений. Можно ли объединить их в один тип? Из того, что я вижу, их поведение здесь одно и то же. Это не исправляет круговую логику, но это может дать вам другое представление о вашем дизайне ...

10
ответ дан falsarella 22 August 2018 в 20:32
поделиться

Вы можете использовать EnumMap и заполнить его в одном из перечислений.

private static EnumMap<Foo, LinkedList<Bar>> enumAMap;

public static void main(String[] args) throws Exception {
    enumAMap = new EnumMap<Foo, LinkedList<Bar>>(Foo.class);
    System.out.println(Bar.values().length); // initialize enums, prevents NPE
    for (Foo a : Foo.values()) {
        for (Bar b : enumAMap.get(a)) {
            System.out.println(a + " -> " + b);
        }
    }
}

public enum Foo {
    Foo1(1),
    Foo2(2);

    private int num;

    private Foo(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }
}

public enum Bar {
    Bar1(1, Foo.Foo1),
    Bar2(2, Foo.Foo1),
    Bar3(3, Foo.Foo2),
    Bar4(4, Foo.Foo2);

    private int num;
    private Foo foo;

    private Bar(int num, Foo foo) {
        this.num = num;
        this.foo = foo;
        if (!enumAMap.containsKey(foo)) {
            enumAMap.put(foo, new LinkedList<Bar>());
        }
        enumAMap.get(foo).addLast(this);
    }

    public int getNum() {
        return num;
    }

    public Foo getFoo() {
        return foo;
    }
}

Выход:

4
Foo1 -> Bar1
Foo1 -> Bar2
Foo2 -> Bar3
Foo2 -> Bar4
0
ответ дан MForm 22 August 2018 в 20:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: