如何在Java中按多个字段排序对象?

时间:2016-01-23 04:38:40

标签: java arrays list sorting vector

我有一个矢量对象。每个对象都有三个字段 -

int v1, v2, v3;

我需要安排这个对象列表,以便它们按这些值递增。我的意思是v1首先被排序,然后如果v1在任何对象中是相同的,v2是有序的,如果v2是相同的v3是有序的 - 就像你按字母顺序排序单词时,首先你先订购第一个字符第二个等等。

我知道我想说的可能听起来令人困惑,请告诉我是否需要改写它

因此我需要得到我的意见:

object 1: v1 = 5, v2 = 6, v3 = 1;
object 2: v1 = 7, v2 = 5, v3 = 3;
object 3: v1 = 5, v2 = 1, v3 = 3;
object 4: v1 = 2, v2 = 5, v3 = 5;
object 5: v1 = 8, v2 = 4, v3 = 6;

这样订购:

object 4: v1 = 2, v2 = 5, v3 = 5;
object 3: v1 = 5, v2 = 1, v3 = 3;
object 1: v1 = 5, v2 = 6, v3 = 1;
object 2: v1 = 7, v2 = 5, v3 = 3;
object 5: v1 = 8, v2 = 4, v3 = 6;

如您所见,对象3和1具有相同的v1,因此它们按v2

排序

请告诉我是否需要进一步详述

3 个答案:

答案 0 :(得分:1)

使用a Sort - Comparable (on the type) or with a separate Comparator。这些都包含在其他地方。

“棘手”的一点是写出比较方法并不是太痛苦。这可以在几个模板中的一个之后完成(在伪代码中,compareTo方法将被编写为适当的,以便它遵循Comparable / Comparator合同):

// Objects supplied to comparing function
Vector a = ..
Vector b = ..

// First component in which the values are not equals
// establishes a 'winner'
int cmp = 0;
if ((cmp = compareTo(a.v1, b.v1)) != 0) return cmp;
if ((cmp = compareTo(a.v2, b.v2)) != 0) return cmp;
if ((cmp = compareTo(a.v3, b.v3)) != 0) return cmp;
return 0;

当然,上面有多种变体,包括显式/嵌套if-constructs和三元条件链接。上面的代码是用来表示比较单个元素和一致性/可扩展性的单一评估的方式。

对于数字,注意溢出并且结果可能不是整数等,compareTo(n1, n2)有时表示为n1 - n2。如果向量中的值是浮点数,那么可能值得在进行比较时考虑epsilon

这是逻辑的另一个可视化:

if (a.v1 < b.v1) return -1;
else if (a.v1 > b.v1) return 1;
else
  if (a.v2 < b.v2) return -1;
  else if (a.v2 > b.v2) return 1;
  else
    if (a.v3 < b.v3) return -1;
    else if (a.v3 > b.v3) return 1;
    else
      return 0;

答案 1 :(得分:1)

使用以下代码对任何数量和任何级别的排序进行排序。

import java.util.*;

public class SortObj implements Comparable{

    int v1=0, v2=0, v3=0;

    public SortObj(int v1, int v2, int v3) {
        this.v1 = v1;
        this.v2 = v2;
        this.v3 = v3;
    }

    public static void main(String[] args) {
        SortObj o1 = new SortObj(1,2,3);
        SortObj o2 = new SortObj(1,4,3);
        SortObj o3 = new SortObj(1,50,3);
        SortObj o4 = new SortObj(1,30,30);
        SortObj o5 = new SortObj(2,20,3);
        SortObj o6 = new SortObj(3,20,3);

        List<SortObj> list = new ArrayList<>();
        list.add(o1);
        list.add(o2);
        list.add(o3);
        list.add(o4);
        list.add(o5);
        list.add(o6);

        Collections.sort(list);
        for(SortObj sortObj : list){
            System.out.println(sortObj.toString());
        }
    }


    @Override
    public String toString() {
        return  String.format("%02d", v1)+
                String.format("%02d", v2)+
                String.format("%02d", v3);
    }
    @Override
    public int compareTo(Object o) {
        return this.toString().compareTo(o.toString());
    }
}

答案 2 :(得分:0)

您可以在类ObjectX中实现Comparable

public int compareTo(final ObjectX 2bj1, final ObjectX obj2) {
...    
}