Java mit enum mit switch-Anweisung


106

Ich habe mir verschiedene Fragen und Antworten zu SO angesehen, die dieser Frage ähnlich sind, aber keine Lösung gefunden.

Was ich habe, ist eine Aufzählung, die verschiedene Möglichkeiten zum Anzeigen eines TV-Programmführers darstellt ...

In der NDroid- ApplicationKlasse

static enum guideView {
    GUIDE_VIEW_SEVEN_DAY,
    GUIDE_VIEW_NOW_SHOWING,
    GUIDE_VIEW_ALL_TIMESLOTS
}

... wenn der Benutzer die Ansicht ändert, erhält ein Ereignishandler eine intvon 0-2 und ich möchte so etwas tun ...

In einem Android- Activity onClick(DialogInterface dialog, int which)Event-Handler

// 'which' is an int from 0-2
switch (which) {
    case NDroid.guideView.GUIDE_VIEW_SEVEN_DAY:
    ...
    break;
}

Ich bin es gewohnt, C # -Aufzählungen und select / case-Anweisungen durchzuführen, die so etwas wie das oben Genannte zulassen, und ich weiß, dass Java die Dinge anders macht, aber ich kann einfach nicht verstehen, was ich tun muss.

Muss ich auf ifAussagen zurückgreifen ? Es wird wahrscheinlich immer nur drei Möglichkeiten geben, damit ich es tun kann, aber ich habe mich gefragt, wie es mit Switch-Case in Java gemacht werden kann.

BEARBEITEN Es tut mir leid, dass ich das Problem nicht vollständig erweitert habe, da ich es als generisches Java-Problem angesehen habe. Ich habe die Frage ergänzt, um sie etwas näher zu erläutern.

Es gibt nichts, was Android-spezifisch ist, weshalb ich es nicht als Android Applicationmarkiert habe, aber die Aufzählung ist in der Klasse definiert und der Code, in dem ich nicht wechseln möchte, befindet sich in einem Activity. Die Aufzählung ist statisch, da ich von mehreren Aktivitäten aus darauf zugreifen muss.


1
Sollte nur case GUIDE_VIEW_SEVEN_DAYnach ordnungsgemäßen Importen sein; Welche Probleme haben Sie?
Dave Newton

Können Sie Ihren Event-Handler nicht einfach dazu bringen, eine Aufzählung zu erhalten? Abgesehen davon hilft dies vielleicht: stackoverflow.com/questions/5292790/…
Brian Roach

@ Dave: Ups, sorry, ich habe den Code korrigiert, um zu zeigen, wie es ist. Eclipse gibt mir einen Typ-Mismatch-Fehler, der besagt, dass es nicht von guideView nach int konvertiert werden kann.
Squonk

@Brian: Dies ist eine Android-App und der Event-Handler ( OnClickListener ) wird durch die DialogInterfaceSchnittstelle definiert , die ich implementieren muss.
Squonk

@MisterSquonk Oh, ich habe vermisst, dass Sie es von einem int bekommen haben - sorry, siehe Ophidians Antwort, obwohl ich die Funktionalität in die Aufzählung aufgenommen habe.
Dave Newton

Antworten:


162

Der Teil, den Sie vermissen, konvertiert von der Ganzzahl in die typsichere Aufzählung. Java macht das nicht automatisch. Es gibt verschiedene Möglichkeiten, dies zu tun:

  1. Verwenden Sie eine Liste statischer Endinten anstelle einer typsicheren Aufzählung und aktivieren Sie den int-Wert, den Sie erhalten (dies ist der Ansatz vor Java 5).
  2. Schalten Sie entweder einen angegebenen ID-Wert (wie von heneryville beschrieben ) oder den Ordnungswert der Aufzählungswerte ein. dhguideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. Bestimmen Sie den Aufzählungswert, der durch den int-Wert dargestellt wird, und schalten Sie dann den Aufzählungswert ein.

    enum GuideView {
        SEVEN_DAY,
        NOW_SHOWING,
        ALL_TIMESLOTS
    }
    
    // Working on the assumption that your int value is 
    // the ordinal value of the items in your enum
    public void onClick(DialogInterface dialog, int which) {
        // do your own bounds checking
        GuideView whichView = GuideView.values()[which];
        switch (whichView) {
            case SEVEN_DAY:
                ...
                break;
            case NOW_SHOWING:
                ...
                break;
        }
    }

    Möglicherweise ist es hilfreicher / weniger fehleranfällig, eine benutzerdefinierte valueOfImplementierung zu schreiben , die Ihre ganzzahligen Werte als Argument verwendet, um den entsprechenden Aufzählungswert aufzulösen und die Überprüfung Ihrer Grenzen zu zentralisieren.


Danke vielmals. Es hat eine Weile gedauert, bis ich es in meinen Code eingearbeitet habe, aber jetzt funktioniert es gut mit dem Beispielcode, den Sie gepostet haben. 6 Jahre mit C # und 1 Jahr mit Java - es kommt nicht oft vor, dass ich auf etwas stoße, das mich verblüfft. So viele Ähnlichkeiten, aber gelegentlich solche, die so unterschiedlich sind. Ich werde diesen nicht so schnell vergessen. :-)
Squonk

2
Sie benötigen die nicht qualifizierten Aufzählungsnamen in der case-Anweisung, daher sollte case GuideView.SEVEN_DAY:ein Kompilierungsfehler auftreten case SEVEN_DAY:.
Haridsv

Es ist großartig, Bruder !!
Neo

41

Wenn whichViewes sich um ein Objekt der GuideView-Enumeration handelt, funktioniert das Folgende gut. Bitte beachten Sie, dass es kein Qualifikationsmerkmal für die Konstante danach gibt case.

switch (whichView) {
    case SEVEN_DAY:
        ...
        break;
    case NOW_SHOWING:
        ...
        break;
}

4
wie ist das überhaupt möglich?!
Jes Chergui

12

Die Aufzählungen sollten innerhalb des Falletiketts nicht wie das, was Sie haben NDroid.guideView.GUIDE_VIEW_SEVEN_DAY, qualifiziert sein , sondern Sie sollten die Qualifikation entfernen und verwendenGUIDE_VIEW_SEVEN_DAY


Bevorzugt diesen. Einfach!
Lazy Ninja

5

Ich mag ein paar Verwendungen von Java-Enumeration:

  1. Mit .name () können Sie den Aufzählungsnamen in String abrufen.
  2. Mit .ordinal () können Sie den 0-basierten Ganzzahlwert abrufen.
  3. Sie können jeder Aufzählung andere Wertparameter hinzufügen.
  4. und natürlich Schalter aktiviert.

Aufzählung mit Wertparametern:

    enum StateEnum {
        UNDEFINED_POLL  ( 1 * 1000L,       4 * 1000L),
        SUPPORT_POLL    ( 1 * 1000L,       5 * 1000L),
        FAST_POLL       ( 2 * 1000L,  4 * 60 * 1000L),
        NO_POLL         ( 1 * 1000L,       6 * 1000L); 
        ...
    }

Beispiel wechseln:

private void queuePoll(StateEnum se) {
    // debug print se.name() if needed
    switch (se) {
        case UNDEFINED_POLL:
            ...
            break;
        case SUPPORT_POLL:
            ...
            break;

3

Dies sollte so funktionieren, wie Sie es beschreiben. Welchen Fehler bekommen Sie? Wenn Sie Ihren Code einfügen könnten, würde das helfen.

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

EDIT: Sind Sie sicher, dass Sie eine statische Aufzählung definieren möchten? Das klingt für mich nicht richtig. Eine Aufzählung ist wie jedes andere Objekt. Wenn Ihr Code kompiliert und ausgeführt wird, aber falsche Ergebnisse liefert, ist dies wahrscheinlich der Grund.


"Verschachtelte Aufzählungstypen sind implizit statisch. Es ist zulässig, einen verschachtelten Aufzählungstyp explizit als statisch zu deklarieren." - JLS §8.9 .
Trashgod

@trashgod, in der Tat - aber ich würde immer die implizite Deklaration verwenden, um Verwirrung zu vermeiden, da dies IMO tatsächlich offensichtlicher ist. Eine globale statische Aufzählung (was ich annehme) ist wahrscheinlich in den meisten Fällen falsch.
SystemParadox

2
enumerations accessing is very simple in switch case

private TYPE currentView;

//declaration of enum 
public enum TYPE {
        FIRST, SECOND, THIRD
    };

//handling in switch case
switch (getCurrentView())
        {
        case FIRST:
            break;
        case SECOND:
            break;
        case THIRD:
            break;
        }

//getter and setter of the enum
public void setCurrentView(TYPE currentView) {
        this.currentView = currentView;
    }

    public TYPE getCurrentView() {
        return currentView;
    }

//usage of setting the enum 
setCurrentView(TYPE.FIRST);

avoid the accessing of TYPE.FIRST.ordinal() it is not recommended always

Das funktioniert nur, wenn Sie Ihre Daten nicht extern abrufen. Da OP sagte, dass der Wert 1, 2, 3 kein TYP ist, würde Ihre Methode ohne einen umgekehrten Schalterfall nicht funktionieren, der 1, 2, 3 nimmt und einen TYP zurückgibt, bevor er in den von ihm aufgelisteten Schalterfall geht.
WORMSS

2

Beispiel für eine kurze assoziative Funktion:

public String getIcon(TipoNotificacao tipo)
{
    switch (tipo){
        case Comentou : return "fa fa-comments";
        case ConviteEnviou : return "icon-envelope";
        case ConviteAceitou : return "fa fa-bolt";
        default: return "";
    }
}

Wie @Dhanushka sagte, lassen Sie das Qualifikationsmerkmal in "switch" weg, das ist der Schlüssel.


1

Ich mache es so

public enum State
{
    // Retrieving, // the MediaRetriever is retrieving music //
    Stopped, // media player is stopped and not prepared to play
    Preparing, // media player is preparing...
    Playing, // playback active (media player ready!). (but the media player
                // may actually be
                // paused in this state if we don't have audio focus. But we
                // stay in this state
                // so that we know we have to resume playback once we get
                // focus back)
    Paused; // playback paused (media player ready!)

    //public final static State[] vals = State.values();//copy the values(), calling values() clones the array

};

public State getState()
{
        return mState;   
}

Und in Switch-Anweisung verwenden

switch (mService.getState())
{
case Stopped:
case Paused:

    playPause.setBackgroundResource(R.drawable.selplay);
    break;

case Preparing:
case Playing:

    playPause.setBackgroundResource(R.drawable.selpause);
    break;    
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.