2012-04-03 11 views
5

Recientemente tuve la necesidad de hacer un escenario de 'caso especial' si solo existe un elemento en la colección. Comprobación de ...size() == 1 y recuperar mediante el uso de ...iterator.next() parecían feas por lo que he creado dos métodos en la clase de cerveza casera Colecciones: haceComprueba si solo existe un elemento usando 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(); 
    } 
} 

Pocos días descubrí que tiene guayaba método llamado Iterables.getOnlyElement. Cubre mi necesidad y reemplaza singleValue, pero no puedo encontrar coincidencias para isSingleValue. ¿Es eso por diseño? ¿Vale la pena solicitar una función para tener el método Iterables.isOnlyElement?

EDIT: Dado que había pocas upvotes decidí abrir la mejora de la guayaba - issue 957. Resolución final - 'WontFix'. Los argumentos son muy similares a lo que Thomas/Xaerxess proporcionó.

Respuesta

10

Bueno, no ganarías mucho si reemplazaste values.size() == 1 por un método, excepto que podrías verificar el nulo. Sin embargo, hay métodos en las Colecciones de Apache Commons (así como en Guava, supongo) para hacer eso.

Prefiero escribir if(values.size() == 1) o if(SomeHelper.size(values) == 1)
que if(SomeHelper.isSingleValue(values)) - la intención es mucho más claro en los dos primeros enfoques y es como mucho código para escribir como con el tercer enfoque.

6

Así, además de otras respuestas (que iba a escribir algo como @daveb que elimina su único: Si no es exactamente un elemento, entonces Iterables#getOnlyElement lanzará una IllegalArgumentException o NoSuchElementException) - una respuesta a la pregunta ¿por qué no hay ningún Iterables.isSingleValue(Iterable) en Guava.

Creo que estás haciendo esto mal. Si:

  • método de invocación no cambia de estado (a diferencia de next() en iterador, por eso existe hasNext())
  • y se puede clara y exlicitly dicen que el valor devuelto no es caso excepcional (a diferencia de null regresaron de Map#get(Object) - puede ser un valor nulo o puede significar que la clave no se ha encontrado en el mapa)

no hay necesidad para el método de comprobación de si la condición es verdadera y luego hacer alguna operación (con la afirmación en él) como en! su código de muestra.

Si está absolutamente seguro de que el iterable en este lugar no puede tener un tamaño distinto de 1, entonces la verificación de condición es redundante (en otros casos se produce una excepción).
Si solo desea obtener el primer elemento en la colección no vacía, collection.iterator.next() está perfectamente OK (NoSuchElementException se lanza si la colección está vacía).
Si no sabe nada sobre el tamaño de la colección que Iterables.getFirst(iterable, default) es para usted.

P.S. Si su Collections#isSingleValue se usa solo localmente aquí (de ahí podría ser privado) que realmente significa que no necesita esa verificación antes de llamar al Iterables#getOnlyValue.

P.P.S.Otra respuesta a su pregunta sobre el diseño de Guava podría ser el Artículo 57 de Joshua Bloch's Effective Java - hay pocos métodos de ayuda en Guava que mencioné anteriormente que explícitamente dicen qué es un caso excepcional para cada uno; La verificación booleana no se agregó debido a que el API es lo más pequeño posible.

0

En este momento estoy teniendo el mismo problema.

voy a resolver con este código:

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

Esto no es clara, ¿qué quiere decir "voy a resolver"? ¿Estás diciendo que esta es una solución o que estás trabajando en el problema? –

+0

Esta es la solución, para mí. – Falci

Cuestiones relacionadas