Anahtar deyimiyle enum kullanan Java


106

SO'da bu soruya benzer çeşitli Soru ve Cevaplara baktım ancak bir çözüm bulamadım.

Sahip olduğum şey, bir TV Rehberini izlemenin farklı yollarını temsil eden bir sıralama ...

NDroid Applicationsınıfında

static enum guideView {
    GUIDE_VIEW_SEVEN_DAY,
    GUIDE_VIEW_NOW_SHOWING,
    GUIDE_VIEW_ALL_TIMESLOTS
}

... kullanıcı görünümü değiştirdiğinde bir olay işleyicisi 0-2'den bir tane alır intve bunun gibi bir şey yapmak istiyorum ...

Bir Android Activity onClick(DialogInterface dialog, int which)olay işleyicisinde

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

Yukarıdaki gibi bir şeye izin veren C # numaralandırmalarına ve select / case ifadelerine alışkınım ve Java'nın işleri farklı şekilde yaptığını biliyorum, ancak ne yapmam gerektiğini anlayamıyorum.

ifİfadelere başvurmam gerekecek mi? Muhtemelen sadece 3 seçenek olacak, bu yüzden yapabilirdim ama Java'da anahtar durumuyla nasıl yapılabileceğini merak ettim.

DÜZENLE Özür dilerim, genel bir Java sorunu olarak baktığım için konuyu tam olarak genişletmedim. Biraz daha açıklamak için soruya ekledim.

Android'e özgü hiçbir şey yok, bu yüzden onu Android olarak etiketlemedim, ancak numaralandırma Applicationsınıfta tanımlı ve anahtar yapmayacağım kod bir Activity. Numaralandırma, birden çok Aktiviteden erişmem gerektiğinden statik.


1
case GUIDE_VIEW_SEVEN_DAYUygun ithalattan sonra olmalı ; Ne sorunlar yaşıyorsunuz?
Dave Newton

Olay işleyicinizin bir sıralama almasını sağlayamaz mısınız? Bunun dışında belki bu yardımcı olacaktır: stackoverflow.com/questions/5292790/…
Brian Roach

@Dave: Üzgünüm, nasıl olduğunu göstermek için kodu düzelttim. Eclipse bana guideView'den int'e dönüştüremeyeceğini söyleyen bir Tür Uyuşmazlığı hatası veriyor.
Squonk

@Brian: Bu bir Android uygulaması ve olay işleyicisi ( OnClickListener ), DialogInterfaceuygulamam gereken arayüz tarafından tanımlanıyor .
Squonk

@MisterSquonk Oh, bunu bir int'ten alacağınızı özledim - üzgünüm, Ophidian'ın cevabına bakın, ancak işlevselliği numaralandırmaya koymuş olsam da.
Dave Newton

Yanıtlar:


162

Eksik olan kısım, tam sayıdan tür güvenli numaralandırmaya dönüştürmektir. Java bunu otomatik olarak yapmayacak. Bunu yapmanın birkaç yolu var:

  1. Tür açısından güvenli bir numaralandırma yerine statik nihai girişlerin bir listesini kullanın ve aldığınız int değerini açın (bu Java 5 öncesi yaklaşımdır)
  2. Belirtilen bir kimlik değerini ( heneryville tarafından açıklandığı gibi ) veya enum değerlerinin sıra değerini açın; yaniguideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. İnt değerinin temsil ettiği enum değerini belirleyin ve ardından enum değerini açın.

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

    valueOfUygun enum değerini çözümlemek için tamsayı değerlerinizi bağımsız değişken olarak alan ve sınır kontrolünüzü merkezileştirmenize olanak tanıyan özel bir uygulama yazmanın daha yararlı / daha az hataya meyilli olduğunu görebilirsiniz .


Çok teşekkürler. Koduma eklemem biraz zaman aldı ama şimdi gönderdiğiniz örnek kodla güzel çalışıyor. C # ile 6 yıl ve Java ile 1 yıl - beni şaşırtan bir şeyle sık sık karşılaşmıyorum. Çok fazla benzerlik var ama ara sıra böyle olan çok farklı. Bunu aceleyle unutmayacağım. :-)
Squonk

2
Case deyiminde nitelenmemiş enum adlarına ihtiyacınız var, bu yüzden case GuideView.SEVEN_DAY:bir derleme hatası veriyor, olmalı case SEVEN_DAY:.
haridsv

Süper kardeşim !!
Neo

42

Eğer whichViewGuideView Enum bir amacı, şu iyi çalışıyor. Lütfen sonra sabiti için bir niteleyici olmadığını unutmayın case.

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

4
bu nasıl mümkün olabilir ?!
Jes Chergui

12

Numaralandırmalar, sahip olduğunuz gibi vaka etiketi içinde nitelendirilmemelidir NDroid.guideView.GUIDE_VIEW_SEVEN_DAY, bunun yerine niteliği kaldırmalı ve kullanmalısınızGUIDE_VIEW_SEVEN_DAY


Bunu tercih ediyor. Basit!
Tembel Ninja

5

Java numarasının birkaç kullanımını seviyorum:

  1. .name (), enum adını String içinde getirmenize olanak sağlar.
  2. .ordinal (), 0 tabanlı tamsayı değerini almanızı sağlar.
  3. Her bir numaralandırma ile diğer değer parametrelerini ekleyebilirsiniz.
  4. ve tabii ki anahtar etkin.

değer parametreleriyle enum:

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

geçiş örneği:

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

3

Bu sizin tarif ettiğiniz şekilde çalışmalıdır. Hangi hatayı alıyorsun? Kodunuzu yapıştırabilirseniz bu yardımcı olur.

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

DÜZENLE: Statik bir numaralandırma tanımlamak istediğinizden emin misiniz? Bu bana doğru gelmiyor. Bir enum, diğer herhangi bir nesneye çok benzer. Kodunuz derler ve çalışır ancak yanlış sonuçlar verirse, muhtemelen nedeni bu olabilir.


"İç içe yerleştirilmiş enum türleri örtük olarak statiktir. İç içe yerleştirilmiş bir enum türünün statik olarak açıkça bildirilmesine izin verilir." - JLS §8.9 .
trashgod

@trashgod, aslında- ama karışıklığı önlemek için her zaman örtük bildirimi kullanırdım, çünkü bu aslında daha açık bir IMO. Genel statik bir enum (ki bunun olduğunu varsayıyorum) çoğu durumda muhtemelen yanlıştır.
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

Bu yalnızca verilerinizi harici olarak almıyorsanız işe yarar. OP, bir TYPE değil 1, 2, 3 değerini döndürdüğünü söylediğinden, yönteminiz, listelediği anahtar durumuna girmeden önce 1, 2, 3 alan ve bir TÜR döndüren ters anahtar durumu olmadan çalışmaz.
WORMSS

2

Kısa ilişkisel işlev örneği:

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

@Dhanushka'nın dediği gibi, anahtar "anahtar" içindeki niteleyiciyi atlayın.


1

Ben gibi yapıyorum

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

Ve Anahtar İfadesinde kullanın

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

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

case Preparing:
case Playing:

    playPause.setBackgroundResource(R.drawable.selpause);
    break;    
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.