开发者社区 问答 正文

java中对ArrayList进行排序


ava如何对ArrayList中对象按照该对象某属性排序
(从小到大)
两种方法:


[tr=none]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
方法一:<br data-filtered="filtered">Comparator<KNNNode> comparator = new Comparator<KNNNode>() {         @Override        public int compare(KNNNode o1, KNNNode o2) {            System.out.println("进入 compare function");            // TODO Auto-generated method stub            if (o1.getDistance() <= o2.getDistance()) {//o1属性小于等于o2属性时,返回1                return 1;            } else {                return -1;            }        }     };

调用方法:


[tr=none]
1
2
3
List<KNNNode> nodelist = new ArrayList<KNNNode>();//此处需要填充nodelist.add();Collections.sort(nodelist, comparator);// 调用





[tr=none]
1
2
3
4
5
6
7
8
9
10
11
方法二:<br>class SortBy implements Comparator {        public int compare(Object obj1, Object obj2) {            KNNNode point1 = (KNNNode) obj1;            KNNNode point2 = (KNNNode) obj2;            if (point1.getDistance() <= point2.getDistance()) {                return 1;            } else {                return 0;            }        }    }

调用方法:


[tr=none]
1
Collections.sort(nodelist, new SortBy());
KNNNode结点内的属性:


[tr=none]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package newKNN; /** * KNN结点类,用来存储最近邻的k个元组相关的信息 */public class KNNNode {    private int index; // 元组标号    private double distance; // 与测试元组的距离    private String seq;//滑动窗口motif序列片段         public KNNNode(int index, double distance, String seq) {        super();        this.index = index;        this.distance = distance;        this.seq = seq;             }    public int getIndex() {        return index;    }    public void setIndex(int index) {        this.index = index;    }    public double getDistance() {        return distance;    }    public void setDistance(double distance) {        this.distance = distance;    }    public String getSeq() {        return seq;    }    public void setSeq(String seq) {        this.seq = seq;    }     }
我想要按照KNNNode的distance属性排序。


若要按照从大到小的顺序排序,如果只是将
>=返回值改为-1
<返回值改为1 会出现异常。
Comparison method violates its general contract!
原因是是实现接口Comparator 的类有问题 在compare中没有处理好两个比较的对象相等的情况
public int compare(KNNNode o1, KNNNode o2);即 o1.getDistance() == o2.getDistance() 时,返回值不是0
我最终的实现代码是:(从大到小排序)


[tr=none]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Comparator<KNNNode> comparator = new Comparator<KNNNode>() {         @Override        public int compare(KNNNode o1, KNNNode o2) {            // TODO Auto-generated method stub            if (o1.getDistance() < o2.getDistance()) {                return 1;            } else if(o1.getDistance() > o2.getDistance()){                return -1;            }else{                return 0;            }        }     };

展开
收起
java亨利 2017-11-30 14:39:07 2785 分享 版权
阿里云 AI 助理回答

按照 KNNNodedistance 属性对 ArrayList 进行排序

以下是两种实现方式,分别从 从小到大从大到小 排序的角度进行说明,并解决您提到的 Comparison method violates its general contract! 问题。


方法一:使用匿名内部类实现 Comparator

通过 Collections.sort 方法结合匿名内部类实现排序。以下是具体代码:

// 定义 Comparator 实现从小到大排序
Comparator<KNNNode> comparator = new Comparator<KNNNode>() {
    @Override
    public int compare(KNNNode o1, KNNNode o2) {
        // 确保处理相等情况时返回 0
        if (o1.getDistance() < o2.getDistance()) {
            return -1;
        } else if (o1.getDistance() > o2.getDistance()) {
            return 1;
        } else {
            return 0;
        }
    }
};

// 调用排序方法
List<KNNNode> nodeList = new ArrayList<>();
// 填充 nodeList
nodeList.add(new KNNNode(1, 3.5, "seq1"));
nodeList.add(new KNNNode(2, 2.1, "seq2"));
nodeList.add(new KNNNode(3, 4.8, "seq3"));

Collections.sort(nodeList, comparator);

从大到小排序 的实现只需调整比较逻辑:

Comparator<KNNNode> comparatorDesc = new Comparator<KNNNode>() {
    @Override
    public int compare(KNNNode o1, KNNNode o2) {
        if (o1.getDistance() > o2.getDistance()) {
            return -1;
        } else if (o1.getDistance() < o2.getDistance()) {
            return 1;
        } else {
            return 0;
        }
    }
};

Collections.sort(nodeList, comparatorDesc);

方法二:定义独立的 Comparator

通过定义一个独立的类实现 Comparator 接口,便于复用和维护。以下是具体代码:

// 定义独立的 Comparator 类
class SortByDistanceAsc implements Comparator<KNNNode> {
    @Override
    public int compare(KNNNode o1, KNNNode o2) {
        if (o1.getDistance() < o2.getDistance()) {
            return -1;
        } else if (o1.getDistance() > o2.getDistance()) {
            return 1;
        } else {
            return 0;
        }
    }
}

class SortByDistanceDesc implements Comparator<KNNNode> {
    @Override
    public int compare(KNNNode o1, KNNNode o2) {
        if (o1.getDistance() > o2.getDistance()) {
            return -1;
        } else if (o1.getDistance() < o2.getDistance()) {
            return 1;
        } else {
            return 0;
        }
    }
}

// 调用排序方法
List<KNNNode> nodeList = new ArrayList<>();
nodeList.add(new KNNNode(1, 3.5, "seq1"));
nodeList.add(new KNNNode(2, 2.1, "seq2"));
nodeList.add(new KNNNode(3, 4.8, "seq3"));

// 从小到大排序
Collections.sort(nodeList, new SortByDistanceAsc());

// 从大到小排序
Collections.sort(nodeList, new SortByDistanceDesc());

关于 Comparison method violates its general contract! 的解决方案

该异常通常是由于 compare 方法未正确处理相等情况(即 o1.getDistance() == o2.getDistance())导致的。根据 Java 的 Comparator 规范,compare 方法必须满足以下条件:

  1. 自反性compare(x, x) 必须返回 0。
  2. 对称性compare(x, y)compare(y, x) 的结果必须互为相反数。
  3. 传递性:如果 compare(x, y) > 0compare(y, z) > 0,则 compare(x, z) > 0

因此,在实现 compare 方法时,必须确保在 o1.getDistance() == o2.getDistance() 时返回 0,避免直接返回非零值。


总结与注意事项

  1. 从小到大排序o1.getDistance() < o2.getDistance() 返回 -1o1.getDistance() > o2.getDistance() 返回 1,相等时返回 0
  2. 从大到小排序o1.getDistance() > o2.getDistance() 返回 -1o1.getDistance() < o2.getDistance() 返回 1,相等时返回 0
  3. 异常处理:确保 compare 方法严格遵守 Comparator 的规范,避免因相等情况未处理而导致运行时异常。

希望以上内容能够帮助您高效实现 ArrayList 中对象的排序!

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: