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 注释建议,在我的例子中,虽然我需要在不同的方法调用上再次重新排序,所以这个解决方案对我有用。