Java 番石榴如何根据另一个列表对列表进行排序?

Java 番石榴如何根据另一个列表对列表进行排序?,java,collections,guava,Java,Collections,Guava,我有由我的用户ID组成的列表。在数据库查询之后,我正在检索List。我想根据第一个Id列表订购此列表列表可能不包括某些ID。什么是番石榴的方式排序这个名单 我不认为番石榴有什么特别的作用。但这只是写下这个比较的问题: Collections.sort(userList, new Comparator<User>() { @Override public int compare(User u1, User u2) { int i1 = idList.i

我有由我的用户ID组成的
列表
。在数据库查询之后,我正在检索
List
。我想根据第一个Id列表订购此列表<代码>列表可能不包括某些ID。什么是番石榴的方式排序这个名单

我不认为番石榴有什么特别的作用。但这只是写下这个比较的问题:

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);
    }
}
Collections.sort(userList,newcomparator(){
@凌驾
公共整数比较(用户u1、用户u2){
inti1=idList.indexOf(u1.getId());
inti2=idList.indexOf(u2.getId());
返回整数比较(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());
    }
}
final Ordering idOrdering=Ordering.explicit(idList);
Collections.sort(userList,newcomparator(){
@凌驾
公共整数比较(用户u1、用户u2){
返回idOrdering.compare(u1.getId(),u2.getId());
}
}
这可能更有效。

使用番石榴的完全“功能”方式将
排序#explicit()
排序#onResultOf()


其他人已经用番石榴回答了你的问题

请注意,您必须使用库中的不可变数据结构,以利用所有优点

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));   
F indexindlist=new F(){
公共整数f(用户u){
返回idList.elementIndex(Equal.intEqual,u.getId()).toNull();
}
};
排序(Ord.intOrd.comap(indexindlist));

使用谷歌番石榴回答更简单

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);
}
类形式{
公共整数索引;//为简单起见,不包括setter/getter
}
List forms=…//列出实例,每个实例都有索引值
//按ui排序索引对表单进行排序。
private static final Ordering sorter=Ordering.natural().onResultOf(新函数(){
@凌驾
公共整数应用(表格){
返回表单索引;
}
});
私有列表排序表单(列表表单){
返回分拣机。分拣副本(表格);
}

以下是如何使用Java8Lambdas实现这一点

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())));
列表ID=…;列表用户=。。。;
//将ID映射到它们的列表索引,以避免重复的indexOf调用
Map rankMap=IntStream.range(0,ids.size()).boxed()
.collect(Collectors.toMap(id::get,Function.identity());
//按id在列表中的位置排序
排序(Comparator.comparing(u->rankMap.get(u.id())));

由于indexOf方法的线性时间要求,这不是很有效。谢谢Hanks:)也喜欢这个库。:)旁白:在Scala中,解决方案将是
userList.sortBy(idList.indexOf(xOf.id))
。我们将得到类似于java 8;)@Premraj、lambda表达式本身不足以实现所有Scala集合这里有很多东西在起作用:、更高的种类、类型类、mixin组合等等@missingfaktor-同意,并且有理由不在java中包含一些提到的特性。。无论如何,至少java会在Java8中获得一些基本的函数行为,这是一个良好的开端:)我认为您需要确保没有null显示为id,正如OP所说的那样,可能会有null。使用Java8,您可以去掉整个函数,改为使用方法引用。然后,该行看起来是这样的(没有额外的函数):Ordering orderById=Ordering.explicit(userid).onResultOf(User::getId);
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));   
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);
}
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())));