9

Lets say I have the following repository:

public interface UserRepository extends JpaRepository<User, Long> {

    @Query("select u from User u")
    Stream<User> streamAllPaged(Pageable pageable);
}

And I want to perform a search:

public Page<User> findAllUsers(Pageable page) {

    Page<User> page = null;
    try (Stream<User> users = userRepository.streamAllPaged(page)) {
            Set<User> users = users.filter(u -> user.getName().equals("foo"))
                    .collect(Collectors.toSet());
            //create page from set?
    }

}

Obviously I could use a sublist and manually insert page sizes etc but I guess that there should be a more "standard" way to do this?

Robert Niestroj
  • 15,299
  • 14
  • 76
  • 119
ChrisGeo
  • 3,807
  • 13
  • 54
  • 92
  • 1
    I would have thought `Collectors.partitioningBy` could help, but without access to a position in the stream in don't see how. – Aaron Nov 03 '16 at 09:46
  • 1
    If you don't mind using another stream, [this question](http://stackoverflow.com/questions/29273705/how-to-paginate-a-list-of-objects-in-java-8) has the answer. – Aaron Nov 03 '16 at 09:55

1 Answers1

11

I'd argue your use case doesn't make too much sense here. If you want to end up with a Page of results eventually, starting with a Stream is just inefficient. You could easily achieve your expected end result with this:

public interface UserRepository extends CrudRepository<User, Long> {

  Page<User> findByName(String name, Pageable pageable);
}

That'd make sure you only read the amount of names you initially request. Using a Stream here is completely subverting the point as filtering on the Stream will require all User instances to be loaded into memory just to invoke the predicate. You definitely want to let the database do that only return the values that match in the first place.

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211