Java: useresti un EnumSet in questo caso?

6

Ho questo strano scenario in cui viene usata la proprietà Java per costruire e la query HQL, e il tipo del campo è Boolean , cioè è in scatola. Mi sono chiesto perché, perché non mi piace pensare ai valori booleani come aventi tre possibili valori, true , false e null . Recentemente ho scoperto che il valore di null ha effettivamente la semantica in questo sistema. Le semantiche sono: true significa "solo non visualizzate", false significa "solo visualizzate" e null significa "tutte". Quindi, se null, il campo viene ignorato quando si crea la query HQL, in modo che il risultato finale contenga sia risultati non visualizzati che visualizzati.

Secondo me questo è un caso in cui dovrebbe essere usato un enum. Qualcosa del genere:

enum ViewStatus {
  VIEWED, UNVIEWED;
}

Il mio dilemma ora è cosa usare per il terzo caso che dovrebbe rappresentare l'unione di queste due costanti? Le due opzioni sono:

  1. Introduci una terza costante enum, ALL .

    enum ViewStatus {
      VIEWED, UNVIEWED, ALL;
    }
    
  2. Utilizza EnumSet .

EnumSet praticamente esiste appositamente per questo scopo, ma ... sembra che ci siano solo due overhead. Soprattutto quando si leggono i valori nella parte del codice che costruisce l'HQL.

Quindi, quali sono i tuoi pensieri? Devo andare con una terza costante enum e refactoring a EnumSet quando sorge la necessità?

Grazie!

Aggiornamento

Vado per un EnumSet perché voglio introdurre metodi su quell'enumerazione che non avrebbe senso essere chiamata su ALL . Ad esempio ViewStatus.isViewed() .

    
posta Ionuț G. Stan 30.08.2011 - 12:32
fonte

2 risposte

2

Preferisco evitare cose come

ViewStatus viewStatus;

poiché introduce una nuova classe senza dare nulla in cambio rispetto a

boolean isViewed;

Ma è una questione di gusti personali.

Impostando il riferimento su null puoi avere un terzo valore, che non è molto buono, dal momento che puoi ottenere un NPE imprevisto da qualche parte; null non è semplicemente un "valore di prima classe".

EnumSet pretty much exists specifically for this purpose, but... it seems like just two much overhead. Especially when reading the values in the part of the code that builds the HQL.

Il sovraccarico di EnumSet è ragionevole, memorizza nella cache la classe e una matrice di tutti i valori e utilizza un long per l'archiviazione dei dati (a condizione che enum sia abbastanza piccola). Il suo metodo equals è abbastanza veloce, ma ovviamente più lento del confronto di riferimento. Hai menzionato l'uso di HQL, quindi molto probabilmente il runtime sarà dominato dall'accesso al database, quindi IMHO sei un'ottimizzazione inutile e prematura.

Talvolta la mutevolezza di EnumSet può essere un problema, ma c'è ImmutableEnumSet in guava.

I'll go for an EnumSet because I want to introduce methods on that enum that wouldn't make sense to be called on ALL. For example ViewStatus.isViewed().

Non penso tu abbia affermato correttamente tutte le tue alternative. Puoi avere entrambi

enum ViewStatus {VIEWED, UNVIEWED}

e

enum ViewStatuses {VIEWED, UNVIEWED, ALL}

dove il secondo è un sostituto di EnumSet . Detto questo, sono d'accordo con la tua decisione.

    
risposta data 01.09.2011 - 10:03
fonte
-2

In questa situazione io uso questo modello:

public class ViewStatusTest {
    public final static class ViewStatus {
        public static final ViewStatus FALSE = new ViewStatus();
        public static final ViewStatus TRUE = new ViewStatus();
        public static final ViewStatus ALL = new ViewStatus();
        private ViewStatus() {
        }
    }
/** @param args */ public static void main(final String[] args) { final ViewStatus vs = ViewStatus.TRUE; if(ViewStatus.FALSE == vs) { System.out.println("FALSE"); } else if(ViewStatus.TRUE == vs) { System.out.println("TRUE"); } else { System.out.println("ALL"); } } }

È ottimizzato perché esegue il test sull'indirizzo interno (non necessario per caricare oggetti e guardare all'interno).
Nella speranza sarà utile per HQL.
I migliori saluti     
risposta data 01.09.2011 - 09:22
fonte

Leggi altre domande sui tag