番石榴的排序方式根据另一个列表?

Cem*_*emo 8 java collections guava

我有List<Integer>我的用户ID.在数据库查询之后,我正在检索List<User>.我想根据第一个Id列表订购此列表.List<User>可能不包括一些ID.什么是Guava排序这个列表的方法?

Eti*_*veu 14

使用番石榴的完全"功能"方式将Ordering#explicit()与之结合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);
    }

}
Run Code Online (Sandbox Code Playgroud)

你可以声明一个内联的匿名函数,但我喜欢在一个单独的类中将我的函数声明为静态工厂方法,以获得更清晰的代码(Java的函数声明的详细程度隐藏在实用程序类中):

/**
 * 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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

正如@Arne在评论中所提到的,这可以在Java 8中简化,使用方法引用而不是UserFunctions类:

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));
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 使用java 8,您可以删除整个函数并使用方法引用.然后该行看起来像这样(并且没有额外的函数):Ordering <User> orderById = Ordering.explicit(userIds).onResultOf(User :: getId); (2认同)

JB *_*zet 10

我不认为番石榴有任何具体的做法.但这只是写这个比较器的问题:

Collections.sort(userList, new Comparator<User>() {
    @Override
    public int compare(User u1, User u2) {
         int i1 = idList.indexOf(u1.getId());
         int i2 = idList.indexOf(u2.getId());
         return Ints.compare(i1, i2);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我考虑一下,它也可以这样实现:

final Ordering<Integer> idOrdering = Ordering.explicit(idList);
Collections.sort(userList, new Comparator<User>() {
    @Override
    public int compare(User u1, User u2) {
         return idOrdering.compare(u1.getId(), u2.getId());
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能更有效率.