Estoy pensando en pedirle a mi equipo, con niveles de habilidades mixtas, que utilicen Google Guava. Antes de Guava, hubiera utilizado las Colecciones Apache (o su versión genérica).¿Es Google Guava "más difícil" de usar que Apache Collections?
Guava, a diferencia de Apache Collections, parece ser más fuerte en algunos aspectos, pero quizás menos fácil de usar para los programadores menos experimentados. Aquí hay un área donde creo que podría ejemplificar eso.
El código que he heredado contiene una gran cantidad de bucle más listas de lo que son mapas en esencia de los valores heterogéneos, sondeando a los valores, haciendo cheques nulos, y luego hacer algo trivial:
boolean foo(final List<MapLike> stuff, final String target) {
final String upperCaseTarget = target.toUpperCase(0;
for(MapLike m : stuff) {
final Maplike n = (MapLike) m.get("hard coded string");
if(n != null) {
final String s = n.get("another hard code string");
if(s != null && s.toUpperCase().equals(upperCaseTarget)) {
return true ;
}
}
return false ;
}
Mi inicial pensamiento era utilizar Apache Colecciones Transformers:
boolean foo(final List<MapLike> stuff, final String target) {
Collection< String> sa = (Collection<String>) CollectionUtils.collect(stuff,
TransformerUtils.chainedTransformer(new Transformer[] {
AppUtils.propertyTransformer("hard coded string"),
AppUtils.propertyTransformer("another hard coded string"),
AppUtils.upperCaseTransformer()
}));
return sa.contains(target.toUpperCase()) ;
}
El uso de guayaba, que podría ir en dos direcciones:
boolean foo(final List<MapLike> stuff, final String target) {
Collection<String> sa = Collections2.transform(stuff,
Functions.compose(AppUtils.upperCaseFunction(),
Functions.compose(AppUtils.propertyFunction("another hard coded string"),
AppUtils.propertyFunction("hard coded string"))));
return sa.contains(target.toUpperCase()) ;
// or
// Iterables.contains(sa, target.toUpperCase());
// which actually doesn't buy me much
}
En comparación con Apache Colecciones, Functions.compose (g, f) invierte el orden "intuitiva": se aplican funciones de derecha a izquierda, en lugar de la derecha de izquierda a "obvio" de TransformerUtils. encadenadoTransformer.
Un problema más sutil es que, como guayaba devuelve una vista en vivo, llamando contains
en la visualización en vivo es probable que se aplique la función (compuesta) varias veces, así que lo que realmente debe hacer es:
return ImmutableSet.copy(sa).contains(target.toUpperCase()) ;
Pero podría tener nulos en mi conjunto transformado, por lo que no puedo hacer eso. Puedo volcarlo en java.util.Collection, por supuesto.
Pero eso no va a ser obvio para mi equipo (menos experimentado), y es probable que se pierda en el calor de la codificación, incluso después de que lo explique. Esperaba que quizás Iterables.contains() "hiciera lo correcto" y supiera alguna instancia de magia para distinguir un proxy de vista en vivo de una simple colección antigua, pero no es así. Eso hace que la guayaba sea más difícil de usar.
Tal vez escribo algo así como un método estático en mi clase de utilidad para manejar esto?
// List always uses linear search? So no value in copying?
// or perhaps I should copy it into a set?
boolean contains(final List list, final Object target) {
return list.contains(target) ;
}
// Set doesn't use linear search, so copy?
boolean contains(final Set set, final Object target) {
//return ImmutableSet.copy(set).contains(target) ;
// whoops, I might have nulls
return Sets.newHashSet(set).contains(target) ;
}
o tal vez solo copiar conjuntos por encima de un determinado tamaño?
// Set doesn't use linear search, so copy?
boolean contains(final Set set, final Object target) {
final Set search = set.size() > 16 : Sets.newHashSet(set) : set ;
return search.contains(target) ;
}
supongo que estoy pidiendo, "por qué no hay un 'más fácil' transform
en guayaba", y supongo que la respuesta es, "muy bien, apenas siempre volcar lo que devuelve en una nueva colección, o escribe tu propia transformación que hace eso ".
Pero si tengo que hacer eso, ¿no podrían otros clientes de las bibliotecas de Guava? Quizás haya una mejor manera en la Guava, que yo no sepa.
"y probablemente se pierda en el calor de la codificación, incluso después de que lo explique". - ¿no tienes inspecciones de código regulares? –
Bueno, el equipo (s) que heredé no. Ahora lo he instituido. Pero preferiría usar el tiempo de revisión para abordar problemas más grandes. Además, si mi equipo tiene la idea de que "las nuevas formas son muy difíciles", no voy a aceptarlo. Y preferiría un equipo que quiera hacer las cosas de la manera correcta, que un equipo que lo hace de la manera correcta solo por temor a la amonestación. – tpdi
orden de argumento compose(): tenía un nivel adecuado de angustia sobre qué camino tomar, así que investigué y encontré aproximadamente el mismo precedente en ambos sentidos. –