Collections.sort 未排序
Collections.sort isn't sorting
我正在使用 Java EE 构建 Web 应用程序(尽管我的问题更多是基于 Java)
在 Servlet 中,我正在从 EJB 获取订单列表。在此订单列表中,有此订单的状态列表(已发送、在码头、未收到...)
我想按州日期对这个州列表进行排序。所以我这样使用 Collections.sort:
for (Command c : commands) {
c.getStateList().sort(new Comparator<State>() {
@Override
public int compare(State o1, State o2) {
return o1.getStateDate().compareTo(o2.getStateDate());
}
});
c.getStateList().sort(Collections.reverseOrder());
}
request.setAttribute("commands", commands);
但是当我显示结果时,状态没有排序。
如您所见,我尝试颠倒顺序,但它也不起作用。
如您所见,我将 Collections.sort 替换为 ListIWantToSort.sort。还是行不通。
关于为什么它不起作用或我如何修复它有什么想法吗?
编辑:这是列表的 getter 及其实例:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "ciiCommande")
private List<Etat> etatList;
@XmlTransient
public List<Etat> getEtatList() {
return etatList;
}
List<Commande> commandes = new ArrayList<Commande>();
我通过 findAll 方法获取命令。
为了显示它们,我使用了:
<c:forEach items="${commandes}" var="cmd">
<td>${cmd.etatList[0].codeStatut.libelleSituation}</td>
</c:forEach>
尝试:
for (Commande c : commandes) {
c.getEtatList().sort(Collections.reverseOrder(new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
return o1.getDateEtat().compareTo(o2.getDateEtat());
}
}));
}
由于你使用的sort方法在Java SE 8的List接口中已经添加,我猜你使用的是Java SE 8。那么你可以改写如下:
commandes.foreach(c ->
c.getEtatList().sort(Comparator.comparing(Etat::getDateEtat).reversed());
);
您首先使用自定义比较器对列表进行排序。然后,您将根据元素的反向 自然 顺序对其进行重新排序 - 而不是您已经应用的自定义顺序。所以第一种排序没有生效,因为列表是由第二种排序重新排序的。请注意 Collections.reverseOrder()
而不是 反转列表 - 它是 natural 顺序的反转(因此 [=12= 中的元素] 必须已经是 Comparable
).
尝试丢掉第二个排序并做:
c.getEtatList().sort(new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
// Note o2/o1 reversed.
return o2.getDateEtat().compareTo(o1.getDateEtat());
}
});
这应该是您需要的:
Comparator<Etat> comparator = new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
return o1.getDateEtat().compareTo(o2.getDateEtat());
}
};
for (Commande c : commandes) {
Collections.sort(c.getEtatList(), comparator);
// or this one: Collections.sort(c.getEtatList(), Collections.reverseOrder(comparator));
}
这按预期工作,您的问题出在其他地方:
public static void main(String[] args) {
List<State> states = Arrays.asList(new State(2015, 1, 1),
new State(2014, 1, 1),
new State(2016, 1, 1));
System.out.println(states); //not ordered
states.sort(new Comparator<State>() {
@Override public int compare(State o1, State o2) {
return o1.getStateDate().compareTo(o2.getStateDate());
}
});
System.out.println(states); //ordered
}
public static class State {
private final LocalDate stateDate;
public State(int year, int month, int day) {
this.stateDate = LocalDate.of(year, month, day);
}
public LocalDate getStateDate() { return stateDate; }
@Override public String toString() { return stateDate.toString(); }
}
请注意,您似乎正在使用 Java 8 并且您的比较器可以写为:
states.sort(comparing(State::getStateDate));
经过几天的斗争,我设法找到了解决办法。
我每次尝试后,列表都没有排序。我仍然不知道为什么。
但我发现了一个注释 @OrderBy,它可以按照我想要的方式对列表进行排序。
谢谢大家的帮助,也许有一天这个问题会得到解决(看到双关语了吗?我很有趣)。
干杯
非常感谢你的问题,因为我刚刚经历过这个问题。我在我的 JPA 实体 class 上实现了 'Comparable'(正如我在其他许多次所做的那样)。在 myMainJPA_Object.getMyList() 上执行 Collections.sort 时,不会调用覆盖的可比方法。
我的解决方法是创建一个新列表作为 ArrayList(例如),执行 .addAll(myObject.getMyList()),然后在该新列表上执行 Collections.sort,然后排序工作(我的可比方法在排序上调用)。例如:
List<ObjectsToSort> tempList = new ArrayList<>();
tempList.addAll(jpaEntity.getListOfStuff());
Collections.sort(tempList);
//Then you could set the list again
jpaEntity.setListOfStuff(tempList);
我真的不喜欢这个解决方案,但我不知道任何其他解决方法,也没有发现任何关于这个问题的信息(直到你的 post)。我喜欢你的 @OrderBy 注释建议,在我的例子中,虽然我需要在不同的方法调用上再次重新排序,所以这个解决方案对我有用。
我正在使用 Java EE 构建 Web 应用程序(尽管我的问题更多是基于 Java)
在 Servlet 中,我正在从 EJB 获取订单列表。在此订单列表中,有此订单的状态列表(已发送、在码头、未收到...)
我想按州日期对这个州列表进行排序。所以我这样使用 Collections.sort:
for (Command c : commands) {
c.getStateList().sort(new Comparator<State>() {
@Override
public int compare(State o1, State o2) {
return o1.getStateDate().compareTo(o2.getStateDate());
}
});
c.getStateList().sort(Collections.reverseOrder());
}
request.setAttribute("commands", commands);
但是当我显示结果时,状态没有排序。
如您所见,我尝试颠倒顺序,但它也不起作用。
如您所见,我将 Collections.sort 替换为 ListIWantToSort.sort。还是行不通。
关于为什么它不起作用或我如何修复它有什么想法吗?
编辑:这是列表的 getter 及其实例:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "ciiCommande")
private List<Etat> etatList;
@XmlTransient
public List<Etat> getEtatList() {
return etatList;
}
List<Commande> commandes = new ArrayList<Commande>();
我通过 findAll 方法获取命令。
为了显示它们,我使用了:
<c:forEach items="${commandes}" var="cmd">
<td>${cmd.etatList[0].codeStatut.libelleSituation}</td>
</c:forEach>
尝试:
for (Commande c : commandes) {
c.getEtatList().sort(Collections.reverseOrder(new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
return o1.getDateEtat().compareTo(o2.getDateEtat());
}
}));
}
由于你使用的sort方法在Java SE 8的List接口中已经添加,我猜你使用的是Java SE 8。那么你可以改写如下:
commandes.foreach(c ->
c.getEtatList().sort(Comparator.comparing(Etat::getDateEtat).reversed());
);
您首先使用自定义比较器对列表进行排序。然后,您将根据元素的反向 自然 顺序对其进行重新排序 - 而不是您已经应用的自定义顺序。所以第一种排序没有生效,因为列表是由第二种排序重新排序的。请注意 Collections.reverseOrder()
而不是 反转列表 - 它是 natural 顺序的反转(因此 [=12= 中的元素] 必须已经是 Comparable
).
尝试丢掉第二个排序并做:
c.getEtatList().sort(new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
// Note o2/o1 reversed.
return o2.getDateEtat().compareTo(o1.getDateEtat());
}
});
这应该是您需要的:
Comparator<Etat> comparator = new Comparator<Etat>() {
@Override
public int compare(Etat o1, Etat o2) {
return o1.getDateEtat().compareTo(o2.getDateEtat());
}
};
for (Commande c : commandes) {
Collections.sort(c.getEtatList(), comparator);
// or this one: Collections.sort(c.getEtatList(), Collections.reverseOrder(comparator));
}
这按预期工作,您的问题出在其他地方:
public static void main(String[] args) {
List<State> states = Arrays.asList(new State(2015, 1, 1),
new State(2014, 1, 1),
new State(2016, 1, 1));
System.out.println(states); //not ordered
states.sort(new Comparator<State>() {
@Override public int compare(State o1, State o2) {
return o1.getStateDate().compareTo(o2.getStateDate());
}
});
System.out.println(states); //ordered
}
public static class State {
private final LocalDate stateDate;
public State(int year, int month, int day) {
this.stateDate = LocalDate.of(year, month, day);
}
public LocalDate getStateDate() { return stateDate; }
@Override public String toString() { return stateDate.toString(); }
}
请注意,您似乎正在使用 Java 8 并且您的比较器可以写为:
states.sort(comparing(State::getStateDate));
经过几天的斗争,我设法找到了解决办法。
我每次尝试后,列表都没有排序。我仍然不知道为什么。
但我发现了一个注释 @OrderBy,它可以按照我想要的方式对列表进行排序。
谢谢大家的帮助,也许有一天这个问题会得到解决(看到双关语了吗?我很有趣)。
干杯
非常感谢你的问题,因为我刚刚经历过这个问题。我在我的 JPA 实体 class 上实现了 'Comparable'(正如我在其他许多次所做的那样)。在 myMainJPA_Object.getMyList() 上执行 Collections.sort 时,不会调用覆盖的可比方法。
我的解决方法是创建一个新列表作为 ArrayList(例如),执行 .addAll(myObject.getMyList()),然后在该新列表上执行 Collections.sort,然后排序工作(我的可比方法在排序上调用)。例如:
List<ObjectsToSort> tempList = new ArrayList<>();
tempList.addAll(jpaEntity.getListOfStuff());
Collections.sort(tempList);
//Then you could set the list again
jpaEntity.setListOfStuff(tempList);
我真的不喜欢这个解决方案,但我不知道任何其他解决方法,也没有发现任何关于这个问题的信息(直到你的 post)。我喜欢你的 @OrderBy 注释建议,在我的例子中,虽然我需要在不同的方法调用上再次重新排序,所以这个解决方案对我有用。