2012-04-03 15 views
5

Recentemente ho avuto bisogno di fare uno scenario 'caso speciale' se nella raccolta è presente un solo elemento. Verifica del ...size() == 1 e il recupero utilizzando ...iterator.next() sembrava brutto così ho creato due metodi nella classe di birra fatta in casa Collezioni:Verificare se esiste un solo elemento utilizzando Guava

public class Collections { 
    public static <T> boolean isSingleValue(Collection<T> values) { 
     return values.size() == 1; 
    } 

    public static <T> T singleValue(Collection<T> values) { 
     Assert.isTrue(isSingleValue(values)); 
     return values.iterator().next(); 
    } 
} 

Pochi giorni fa ho scoperto che Guava ha metodo chiamato Iterables.getOnlyElement. Copre il mio bisogno e sostituisce singleValue, ma non riesco a trovare la corrispondenza per isSingleValue. È per progetto? Vale la pena mettere la richiesta di funzionalità per il metodo Iterables.isOnlyElement?

EDIT: Dato che c'erano poche upvotes ho deciso di aprire la valorizzazione sul guava - issue 957. Risoluzione finale - 'WontFix'. Gli argomenti sono molto simili a quelli forniti da Thomas/Xaerxess.

risposta

10

Bene, non guadagneresti molto sostituendo values.size() == 1 con un metodo, eccetto che potresti verificare null. Tuttavia, ci sono metodi in Apache Commons Collections (così come in Guava, presumo) per farlo.

preferisco scrivere if(values.size() == 1) o if(SomeHelper.size(values) == 1)
rispetto if(SomeHelper.isSingleValue(values)) - l'intento è molto più chiara nei primi due approcci ed è il più codice per scrivere come con il terzo approccio.

6

Proprio in aggiunta alle altre risposte (stavo per scrivere qualcosa di simile @daveb che cancellato il suo unico: Se non c'è esattamente un elemento, quindi Iterables#getOnlyElement genera un IllegalArgumentException o NoSuchElementException) - una risposta alla domanda perché non c'è alcun Iterables.isSingleValue(Iterable) in Guava.

Penso che tu stia sbagliando. Se:

  • metodo di invocazione non cambia stato (a differenza next() in iteratore, è per questo che esiste hasNext())
  • e si può chiaramente e exlicitly dire che il valore restituito non è caso eccezionale (a differenza null tornato da Map#get(Object) - può essere valore nullo oppure può significare che la chiave non è stata trovata nella mappa)

non c'è bisogno di controllare il metodo se la condizione è vera e quindi fare qualche operazione (con asserzione in esso!) come in il tuo codice di esempio.

Se si è assolutamente certi che l'iterabile in questo punto non possa avere dimensioni diverse da 1, il controllo delle condizioni è ridondante (eccezione viene generata in altri casi).
Se si desidera ottenere solo il primo elemento nella raccolta non vuota - collection.iterator.next() è perfettamente OK (NoSuchElementException viene generato se la raccolta è vuota).
Se non si conosce nulla delle dimensioni della collezione, Iterables.getFirst(iterable, default) fa al caso vostro.

P.S. Se il tuo Collections#isSingleValue utilizzato solo qui localmente (quindi potrebbe essere privato) che in realtà significa che non è necessario tale controllo prima di chiamare Iterables#getOnlyValue.

P.P.S.Un'altra risposta alla tua domanda sul design di Guava potrebbe essere la voce 57 di Joshua Bloch Java efficace - ci sono pochi diversi metodi di supporto in Guava che ho menzionato prima, che dicono esplicitamente che cosa è un caso eccezionale per ognuno; il controllo booleano non è stato aggiunto per mantenere API il più piccolo possibile.

0

In questo momento sto avendo lo stesso problema.

sarò per risolvere con questo codice:

public static <T> void hasJustOne(T... values) { 
    hasJustOne(Predicates.notNull(), values); 
} 

public static <T> void hasJustOne(Predicate<T> predicate, T... values) { 
    Collection<T> filtred = Collections2.filter(Arrays.asList(values),predicate); 
    Preconditions.checkArgument(filtred.size() == 1); 
} 
+0

Questo non è chiaro, che cosa significa "io per risolvere" significa? Stai dicendo che questa è una soluzione o che stai lavorando al problema? –

+0

Questa è la soluzione, per me. – Falci

Problemi correlati