当我在自定义对象的数组列表上使用Collections.sort时,不保留顺序

时间:2021-08-02 19:42:54

I have made some objects which have a property that is an integer, this property is dependent on another objects generated by another class. I have also made a comparator to sort them in an ArrayList according to that property. However, when I sort with this comparator it seems to revert back to the initial order immediately afterwards. Here is an example using dogs and breeds of the comparator I have written:

我创建了一些具有整数属性的对象,该属性依赖于另一个类生成的另一个对象。我还制作了一个比较器,根据该属性在ArrayList中对它们进行排序。但是,当我用这个比较器排序时,它似乎立即恢复到初始顺序。这是一个使用我写的比较器的狗和品种的例子:

    public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        return pos1 - pos2;
    }
};

I then try to create a method that will always return the second biggest breed:

然后我尝试创建一个始终返回第二大品种的方法:

public static Party getSecBigBreed() {
    Collections.sort(breeds, BreedSizeComparator);
    return breeds.get(1);
}

When I call this though I get the breed that was at position 1 in the arraylist initially (before I did the sort). From the research I have done, it seems that it might have something to do with the fact that I put the arraylist of all the breeds created as a class variable of Breed. E.g. the class Breed is such that:

当我打电话给这个时虽然我最初得到了arraylist中位置1的品种(在我进行排序之前)。从我所做的研究来看,似乎它可能与我将所有品种的arraylist作为品种的变量创建的事实有关。例如。品种是这样的:

public class Breed {
private int size = 0;
private int type;
private static ArrayList<Breed> breeds = new ArrayList<Breed>();

public Breed(int type0) {
    type = type0;
    breeds.add(this);
}

I have also made a method in this breed class, to add one to size that I use each time a dog of that type is made, and another to get the breed according to its type, as well as the method to get breed size:

我还在这个品种类中制作了一个方法,在每次制作该类型的狗时使用一个大小,另一个根据其类型获得该品种,以及获得品种大小的方法:

public void increaseSize() {
    this.Size++;
}

public static Breed getBreed(int type0) {
    for(int i = 0; i < breeds.size(); i++) {
         if(type0 = breeds.get(i).type) {
              return breeds.get(i);
         }
    }
}

public int getBreedSize() {
    return size;
}

Here is my dog class:

这是我的狗班:

public class Dog {
private int type;
private int dogNumber;
private static ArrayList<Dog> dogs = new ArrayList<Dog>();

public Dog(int type0) {
    type = type0;
    getBreed(type).increaseSize();
}

Can't really figure out why when I sort the ArrayList breeds according to the size of the breed, it then reverts back to the original ordering.

无法弄清楚为什么当我根据品种的大小对ArrayList品种进行排序时,它会恢复原始排序。

2 个解决方案

#1


1  

Still looking through everything but one thing stood out to me:

仍然看着一切,但有一件事对我来说很突出:

    public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        return pos1 - pos2;
    }
};

I don't know what the values of these are but it's important to note how compare works:

我不知道这些的价值是什么,但重要的是要注意比较是如何工作的:

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.

比较它的两个参数的顺序。返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。在前面的描述中,符号sgn(表达式)指定数学符号函数,其被定义为根据表达式的值是负,零还是正来返回-1,0或1中的一个。

So if pos1 and pos2 are both negative, positive, or equal, you may see unexpected or even no movement within the list

因此,如果pos1和pos2都是负数,正数或相等,您可能会在列表中看到意外甚至没有移动

I would suggest something along these lines:

我会建议这些方面:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        if (pos1 > pos2) {
            return 1;
        } else if (pos2 > pos1) {
            return -1;
        } else {
            return 0;
        }
    }
};

EDIT: as Thomas Jungblut pointed out, an even simpler solution would be:

编辑:正如Thomas Jungblut指出的那样,一个更简单的解决方案是:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        return Integer.valueOf(pos1).compareTo(pos2);
    }
};

what 'compareTo' does is return a 0 if both values are equal, a negative value if the first argument is less than the second, and a positive value if the first argument is greater than the second.

'compareTo'的作用是,如果两个值相等则返回0;如果第一个参数小于第二个,则返回负值;如果第一个参数大于第二个参数,则返回正值。

#2


0  

The comparator needed to be the other way around:

比较器需要反过来:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
@Override
public int compare(Breed o1, Breed o2) {

    int pos1 = o1.getBreedSize();
    int pos2 = o2.getBreedSize();

    //return pos1 - pos2;

    //ArrayList needs to be in descending order
    return pos1 - pos2;
}
};

#1


1  

Still looking through everything but one thing stood out to me:

仍然看着一切,但有一件事对我来说很突出:

    public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        return pos1 - pos2;
    }
};

I don't know what the values of these are but it's important to note how compare works:

我不知道这些的价值是什么,但重要的是要注意比较是如何工作的:

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.

比较它的两个参数的顺序。返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。在前面的描述中,符号sgn(表达式)指定数学符号函数,其被定义为根据表达式的值是负,零还是正来返回-1,0或1中的一个。

So if pos1 and pos2 are both negative, positive, or equal, you may see unexpected or even no movement within the list

因此,如果pos1和pos2都是负数,正数或相等,您可能会在列表中看到意外甚至没有移动

I would suggest something along these lines:

我会建议这些方面:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        if (pos1 > pos2) {
            return 1;
        } else if (pos2 > pos1) {
            return -1;
        } else {
            return 0;
        }
    }
};

EDIT: as Thomas Jungblut pointed out, an even simpler solution would be:

编辑:正如Thomas Jungblut指出的那样,一个更简单的解决方案是:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
    @Override
    public int compare(Breed o1, Breed o2) {

        int pos1 = o1.getBreedSize();
        int pos2 = o2.getBreedSize();

        return Integer.valueOf(pos1).compareTo(pos2);
    }
};

what 'compareTo' does is return a 0 if both values are equal, a negative value if the first argument is less than the second, and a positive value if the first argument is greater than the second.

'compareTo'的作用是,如果两个值相等则返回0;如果第一个参数小于第二个,则返回负值;如果第一个参数大于第二个参数,则返回正值。

#2


0  

The comparator needed to be the other way around:

比较器需要反过来:

public static Comparator<Breed> BreedSizeComparator = new Comparator<Breed>() {
@Override
public int compare(Breed o1, Breed o2) {

    int pos1 = o1.getBreedSize();
    int pos2 = o2.getBreedSize();

    //return pos1 - pos2;

    //ArrayList needs to be in descending order
    return pos1 - pos2;
}
};