3838import com .google .firebase .firestore .pipeline .InternalOptions ;
3939import com .google .firebase .firestore .pipeline .Ordering ;
4040import com .google .firebase .firestore .pipeline .BaseStage ;
41+ import com .google .firebase .firestore .util .BiFunction ;
42+ import com .google .firebase .firestore .util .Function ;
43+ import com .google .firebase .firestore .util .IntFunction ;
4144import com .google .firestore .v1 .Value ;
4245import java .util .ArrayList ;
4346import java .util .Collections ;
4649import java .util .List ;
4750import java .util .SortedSet ;
4851import java .util .TreeSet ;
49- import java .util .function .BiFunction ;
5052
5153/**
5254 * Encapsulates all the query attributes we support in the SDK. It can be run against the
@@ -547,8 +549,7 @@ public Pipeline toPipeline(FirebaseFirestore firestore, UserDataReader userDataR
547549 if (fields .size () == 1 ) {
548550 p = p .where (fields .get (0 ).exists ());
549551 } else {
550- BooleanExpr [] conditions =
551- fields .stream ().skip (1 ).map (Expr .Companion ::exists ).toArray (BooleanExpr []::new );
552+ BooleanExpr [] conditions = skipFirstToArray (fields , BooleanExpr []::new , Expr .Companion ::exists );
552553 p = p .where (and (fields .get (0 ).exists (), conditions ));
553554 }
554555
@@ -564,23 +565,43 @@ public Pipeline toPipeline(FirebaseFirestore firestore, UserDataReader userDataR
564565 if (hasLimit ()) {
565566 // TODO: Handle situation where user enters limit larger than integer.
566567 if (limitType == LimitType .LIMIT_TO_FIRST ) {
567- p = p .sort (orderings .get (0 ), orderings . stream (). skip ( 1 ). toArray ( Ordering []::new ));
568+ p = p .sort (orderings .get (0 ), skipFirstToArray ( orderings , Ordering []::new ));
568569 p = p .limit ((int ) limit );
569570 } else {
570571 p =
571572 p .sort (
572573 orderings .get (0 ).reverse (),
573- orderings . stream (). skip ( 1 ). map ( Ordering :: reverse ). toArray ( Ordering []::new ));
574+ skipFirstToArray ( orderings , Ordering []::new , Ordering :: reverse ));
574575 p = p .limit ((int ) limit );
575- p = p .sort (orderings .get (0 ), orderings . stream (). skip ( 1 ). toArray ( Ordering []::new ));
576+ p = p .sort (orderings .get (0 ), skipFirstToArray ( orderings , Ordering []::new ));
576577 }
577578 } else {
578- p = p .sort (orderings .get (0 ), orderings . stream (). skip ( 1 ). toArray ( Ordering []::new ));
579+ p = p .sort (orderings .get (0 ), skipFirstToArray ( orderings , Ordering []::new ));
579580 }
580581
581582 return p ;
582583 }
583584
585+ // Many Pipelines require first parameter to be separated out from rest.
586+ private static <T > T [] skipFirstToArray (List <T > list , IntFunction <T []> generator ) {
587+ int size = list .size ();
588+ T [] result = generator .apply (size - 1 );
589+ for (int i = 1 ; i < size ; i ++) {
590+ result [i -1 ] = list .get (i );
591+ }
592+ return result ;
593+ }
594+
595+ // Many Pipelines require first parameter to be separated out from rest.
596+ private static <T , R > R [] skipFirstToArray (List <T > list , IntFunction <R []> generator , Function <T , R > map ) {
597+ int size = list .size ();
598+ R [] result = generator .apply (size - 1 );
599+ for (int i = 1 ; i < size ; i ++) {
600+ result [i -1 ] = map .apply (list .get (i ));
601+ }
602+ return result ;
603+ }
604+
584605 private static BooleanExpr whereConditionsFromCursor (
585606 Bound bound , List <Field > fields , BiFunction <Expr , Object , BooleanExpr > cmp ) {
586607 List <Value > boundPosition = bound .getPosition ();
0 commit comments