I have List<Integer>
consisting Ids of my Users. And after a database query, I am retrieving List<User>
. I would like to order this list according to first Id list. List<User>
may not include some of the Ids. What is the Guava way for sorting this list?
The fully "functional" way, using Guava, would combine Ordering#explicit()
with Ordering#onResultOf()
public class UserService {
@Inject private UserDao userDao;
public List<User> getUsersWithIds(List<Integer> userIds) {
List<User> users = userDao.loadUsersWithIds(userIds);
Ordering<User> orderById = Ordering.explicit(userIds).onResultOf(UserFunctions.getId());
return orderById.immutableSortedCopy(users);
}
}
You could declare an anonymous function inline, but I like to declare my functions as static factory methods in a separate class, for a cleaner code (the verbosity of Java's function declarations is hidden in the utility class):
/**
* Static factory methods to create {@link Function}s for {@link User}s.
*/
public final class UserFunctions {
private UserFunctions() { /* prevents instantiation */ }
/**
* @return a {@link Function} that returns an {@link User}'s id.
*/
public static Function<User, Integer> getId() {
return GetIdFunction.INSTANCE;
}
// enum singleton pattern
private enum GetIdFunction implements Function<User, Integer> {
INSTANCE;
public Integer apply(User user) {
return user.getId();
}
}
}
As mentioned by @Arne in a comment, this can be simplified in Java 8, using a method reference instead of the UserFunctions
class:
public class UserService {
@Inject private UserDao userDao;
public List<User> getUsersWithIds(List<Integer> userIds) {
List<User> users = userDao.loadUsersWithIds(userIds);
Ordering<User> orderById = Ordering.explicit(userIds).onResultOf(User::getId);
return orderById.immutableSortedCopy(immutableSortedCopy(users));
}
}