List<Integer>
ユーザーの ID を構成しています。そして、データベース クエリの後、取得していList<User>
ます。このリストを最初の Id リストに従って並べたいと思います。List<User>
一部の ID が含まれていない場合があります。このリストを並べ替える Guava の方法は何ですか?
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が述べたように、これはUserFunctions
クラスの代わりにメソッド参照を使用して、Java 8で簡素化できます。
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 を使用してあなたの質問に答えています。これがFunctional 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ラムダでこれを行う方法は次のとおりです。
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 に答える