Я подумываю просить мою команду о смешанных уровнях навыков использовать Google Guava. До Guava я бы использовал Apache Collections (или его расширенную версию).
Гуава, в отличие от Apache Collections, кажется в какой-то степени сильнее, но, возможно, менее проста в использовании для менее опытных программистов. Здесь одна область, где, на мой взгляд, может служить примером.
Код, который я унаследовал, содержит много циклов над списками того, что по существу является картами гетерогенных значений, исследуя их для значений, делая нулевые проверки, а затем делая что-то тривиальное:
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 ;
}
Моя первоначальная мысль заключалась в использовании Apache Collections 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() ) ;
}
Используя Guava, я могу пойти двумя способами:
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
}
По сравнению с коллекциями Apache функции .com.com(g, f) меняют "интуитивный" порядок: функции применяются справа налево, а не "очевидные" слева направо от TransformerUtils.chainedTransformer.
Более тонкая проблема заключается в том, что, поскольку Guava возвращает живое представление, вызов contains
в режиме просмотра в реальном времени, скорее всего, применит (сложенную) функцию несколько раз, поэтому мне действительно нужно:
return ImmutableSet.copy( sa ).contains( target.toUpperCase() ) ;
Но у меня могут быть нули в моем преобразованном наборе, поэтому я не могу этого сделать. Я могу сбросить его в java.util.Collection, конечно.
Но это не будет очевидно для моей (менее опытной) команды и, вероятно, будет пропущено в разгаре кодирования даже после того, как я объясню это. Я надеялся, что, возможно, Iterables.contains() "пойдет правильно" и узнает какой-то экземпляр магии, чтобы отличить прокси-сервер в реальном времени от простой старой коллекции, но это не так. Это делает Гуаву, возможно, труднее использовать.
Возможно, я пишу что-то вроде статического метода в моем классе утилиты, чтобы справиться с этим?
// 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 ) ;
}
или, возможно, только экземпляры копий выше определенного размера?
// 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 ) ;
}
Я полагаю, что я спрашиваю: "Почему в Guava нет" легче "transform
, и я полагаю, что ответ" отлично, просто всегда дампируйте то, что он возвращает в новую коллекцию, или напишите ваше собственное преобразование, которое делает это ".
Но если мне нужно это сделать, возможно, не другие клиенты библиотек Guava? Возможно, есть лучший способ, который есть в Гуаве, о котором я не знаю?