我已经List<Integer>
组成了我的用户的 ID。在数据库查询之后,我正在检索List<User>
. 我想根据第一个 ID 列表订购此列表。List<User>
可能不包括某些 Id。排序此列表的番石榴方式是什么?
问问题
10940 次
6 回答
14
使用 Guava 的完全“功能性”方式将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);
}
}
您可以内联声明一个匿名函数,但我喜欢在单独的类中将我的函数声明为静态工厂方法,以获得更简洁的代码(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();
}
}
}
正如@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));
}
}
于 2012-06-07T11:50:23.913 回答
11
我不认为番石榴有什么特别的东西可以做到这一点。但这只是编写这个比较器的问题:
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);
}
}
现在想来,也可以这样实现:
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());
}
}
这可能更有效。
于 2012-06-07T11:12:06.173 回答
2
其他人已经使用 Guava 回答了您的问题。这是一个函数式 Java答案。
请注意,您必须使用库中的不可变数据结构才能利用所有优点。
F<User, Integer> indexInIdList = new F<User, Integer>() {
public Integer f(User u) {
return idList.elementIndex(Equal.intEqual, u.getId()).toNull();
}
};
userList.sort(Ord.intOrd.comap(indexInIdList));
于 2012-06-07T11:57:14.017 回答
0
使用 Google Guava 更简单的答案
class Form {
public Integer index; // for simplicity, no setter/getter included
}
List<Form> forms = ... // list instances, each of each with values for index
// ordering of forms by the ui sort index.
private static final Ordering<Form> sorter = Ordering.natural().onResultOf(new Function<Form, Integer>() {
@Override
public Integer apply(Form form) {
return form.index;
}
});
private List<Form> sortForms(List<Form> forms) {
return sorter.sortedCopy(forms);
}
于 2013-11-22T20:29:01.340 回答
0
以下是如何使用 Java 8 lambdas 做到这一点。
List<Integer> ids = ...; List<User> users = ...;
//map ids to their list indices, to avoid repeated indexOf calls
Map<Integer, Integer> rankMap = IntStream.range(0, ids.size()).boxed()
.collect(Collectors.toMap(ids::get, Function.identity()));
//sort on the id's position in the list
users.sort(Comparator.comparing(u -> rankMap.get(u.id())));
于 2014-09-23T14:42:34.237 回答
0
几乎没有找到 Kotlin 的答案,所以我在这里发布。
list2.sortedBy { Pair(it, list1.indexOf(it.typeOfList1)).second }
我写的完整的 TU 是为了找到答案:
enum class Categorie { UNO, DOS, TRES, QUATROS }
data class Song(val name: String, val categorie: Categorie)
fun main() {
val categories = arrayListOf(Categorie.QUATROS, Categorie.DOS, Categorie.TRES, Categorie.UNO)
val songs = arrayListOf(
Song("s1", Categorie.DOS),
Song("s2", Categorie.DOS),
Song("s3", Categorie.UNO),
Song("s4", Categorie.QUATROS),
Song("s5", Categorie.TRES),
Song("s6", Categorie.QUATROS)
)
val expectedSortedListOfSongs = arrayListOf(
Song("s4", Categorie.QUATROS),
Song("s6", Categorie.QUATROS),
Song("s1", Categorie.DOS),
Song("s2", Categorie.DOS),
Song("s5", Categorie.TRES),
Song("s3", Categorie.UNO)
)
val sortedList: List<Song> = songs.sortedBy { Pair(it, categories.indexOf(it.categorie)).second }
println("isValid=${sortedList == expectedSortedListOfSongs}")
}
于 2021-08-31T12:42:49.260 回答