给出错误结果的子列表的Java倒序

给出错误结果的子列表的Java倒序,java,sorting,arraylist,collections,Java,Sorting,Arraylist,Collections,我有个问题。我将代码简化为一个小的演示程序。有一个名为Visitor的类,它如下所示: public class Visitor implements Comparable<Visitor> { private Integer id; private String name; private static int lastIdGiven = 0; public Visitor(Integer id) { this.id = id;

我有个问题。我将代码简化为一个小的演示程序。有一个名为
Visitor
的类,它如下所示:

public class Visitor implements Comparable<Visitor> {

    private Integer id;
    private String name;
    private static int lastIdGiven = 0;

    public Visitor(Integer id) {
        this.id = id;
    }

    public Visitor(String name) {
        this.id = getNewId();
        this.name = name;
    }

    private int getNewId() {
        this.lastIdGiven++;
        return this.lastIdGiven;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Visitor o) {
        return this.id.compareTo(o.id);
    }
}
但是现在我想对5个访客进行反向排序。为此,我将代码注释掉,但我有以下几行:

foundVisitors.sort(Visitor::compareTo);
foundVisitors.sort(Collections.reverseOrder());
然而,这导致了一个非常奇怪的列表,它从原始列表中获取旧数据:

For visitor-Id: 19, are the following visitors found:
    Id: 18
    Id: 4
    Id: 3
    Id: 2
    Id: 1
我想我会得到以下输出:

For visitor-Id: 19, are the following visitors found:
        Id: 18
        Id: 17
        Id: 16
        Id: 15
        Id: 14
这里给出的代码是我的整个项目,所以你们可以复制它,如果你们愿意:)

出现了什么问题以及如何解决此问题?

要解决您的问题,您只需执行以下操作,更换:

List<Visitor> foundVisitors = visitorList.subList(startIndex, endIndex);
foundVisitors.sort(Collections.reverseOrder());
           
旁注:

    for (Integer i = 0; i < 20; i++) {
        Visitor visitor = new Visitor("visitor " + i.toString());
        visitorList.add(visitor);
    }
for(整数i=0;i<20;i++){
访客=新访客(“访客”+i.toString());
访问者列表。添加(访问者);
}
可简化为:

    for (int i = 0; i < 20; i++) {
        Visitor visitor = new Visitor("visitor " + i);
        visitorList.add(visitor);
    }
for(int i=0;i<20;i++){
访客=新访客(“访客”+i);
访问者列表。添加(访问者);
}
更新:

与您的问题的主要问题无关,但仍然是一个值得一提的优化。建议人:

使用基于索引的循环将消除执行二进制循环的需要 搜索您已经知道其位置的元素。事实上,你 可以从该索引向后循环并打印五个元素,然后 您既不需要子列表,也不需要反向排序

因此,您的代码可以简化为:

public static void main(String[] args) {

    ArrayList<Visitor> visitorList = new ArrayList<>();

    for (int i = 0; i < 20; i++) {
        Visitor visitor = new Visitor("visitor " + i);
        visitorList.add(visitor);
    }
    visitorList.sort(Visitor::compareTo);
    for(int i = NUM_OF_VISITORS_IN_LIST; i < visitorList.size(); i++) {
        System.out.println("For visitor: " + visitorList.get(i));
        for(int j = i, end = i - NUM_OF_VISITORS_IN_LIST; j > end;) {
            System.out.println(visitorList.get(--j).getId());
        }
        System.out.println();
    }
}
publicstaticvoidmain(字符串[]args){
ArrayList visitorList=新建ArrayList();
对于(int i=0;i<20;i++){
访客=新访客(“访客”+i);
访问者列表。添加(访问者);
}
visitorList.sort(Visitor::compareTo);
for(int i=列表中访问者的数量;iend;){
System.out.println(visitorList.get(--j.getId());
}
System.out.println();
}
}

排序很好。我忽略了你的循环,就这么做了

 visitorList.sort(Comparator.comparing(Visitor::getId));
 visitorList.forEach(System.out::println);
 visitorList.sort(Comparator.comparing(Visitor::getId).reversed());
 visitorList.forEach(System.out::println);
它们按预期进行排序和打印

我建议您将其放在Visitor类中,以便只打印对象

@Override
public String toString() {
    return name + " " + id;
}

不要修改您的
子列表
。否则,您将更改原件的内容。如果您对子列表进行排序,它将只对这些项目进行排序。然后,当您打印原始列表中的项目时,只有
子列表
部分将被排序。

这里的问题在于您使用方法sublist()的方式,特别是以下语句:

List foundVisitors=visitorList.subList(startIndex,endIndex)

根据列表的方法子列表的Java规范:

返回的列表由该列表支持,因此返回列表中的非结构性更改将反映在此列表中,反之亦然

这意味着,当您在子列表“foundVisitors”中应用“sort”时,它将立即反映在主列表“visitorList”中,最终结果将是一片混乱

要解决此问题,您必须从子列表中创建一个新列表,例如,您可以将行替换为以下行:

   List<Visitor> foundVisitors = new ArrayList<>(visitorList.subList(startIndex, endIndex));

   // REVERSE THE SORTING
   Collections.sort(foundVisitors, Collections.reverseOrder());
List foundVisitors=newarraylist(visitorList.subList(startIndex,endIndex));
//反向排序
Collections.sort(foundVisitors,Collections.reverseOrder());

试试这个,看看它是如何工作的。

谢谢!你解释得很清楚:)
public static void main(String[] args) {

    ArrayList<Visitor> visitorList = new ArrayList<>();

    for (int i = 0; i < 20; i++) {
        Visitor visitor = new Visitor("visitor " + i);
        visitorList.add(visitor);
    }
    visitorList.sort(Visitor::compareTo);
    for(int i = NUM_OF_VISITORS_IN_LIST; i < visitorList.size(); i++) {
        System.out.println("For visitor: " + visitorList.get(i));
        for(int j = i, end = i - NUM_OF_VISITORS_IN_LIST; j > end;) {
            System.out.println(visitorList.get(--j).getId());
        }
        System.out.println();
    }
}
 visitorList.sort(Comparator.comparing(Visitor::getId));
 visitorList.forEach(System.out::println);
 visitorList.sort(Comparator.comparing(Visitor::getId).reversed());
 visitorList.forEach(System.out::println);
@Override
public String toString() {
    return name + " " + id;
}
   List<Visitor> foundVisitors = new ArrayList<>(visitorList.subList(startIndex, endIndex));

   // REVERSE THE SORTING
   Collections.sort(foundVisitors, Collections.reverseOrder());