public static Iterable < Imp > impsWith ( BidRequest request , Predicate < Imp > impFilter ) { checkNotNull ( impFilter ) ; List < Imp > imps = request . getImpList ( ) ; if ( imps . isEmpty ( ) || impFilter == IMP_ALL ) { return imps ; } else if ( impFilter == IMP_NONE ) { return ImmutableList . of ( ) ; } boolean included = impFilter . test ( imps . get ( 0 ) ) ; int size = imps . size ( ) , i ; for ( i = 1 ; i < size ; ++ i ) { if ( impFilter . test ( imps . get ( i ) ) != included ) { break ; } } if ( i == size ) { return included ? imps // Unmodifiable, comes from protobuf : ImmutableList . < Imp > of ( ) ; } int headingSize = i ; return new FluentIterable < Imp > ( ) { @ Override public Iterator < Imp > iterator ( ) { Iterator < Imp > unfiltered = imps . iterator ( ) ; return new AbstractIterator < Imp > ( ) { private int heading = 0 ; @ Override protected Imp computeNext ( ) { while ( unfiltered . hasNext ( ) ) { Imp imp = unfiltered . next ( ) ; if ( ( heading ++ < headingSize ) ? included : impFilter . test ( imp ) ) { return imp ; } } return endOfData ( ) ; } } ; } } ; }
Optimized code for most filtered lookups . This is worth the effort because bidder code may invoke these lookup methods intensely ; common cases like everything - filtered or nothing - filtered are very dominant ; and simpler code previously used needed lots of temporary collections .