0

首先,我在发帖之前确实做了功课搜索。与那里发布的问题相比,我的要求似乎略有不同。

我有一个ArrayList<ArrayList<Integer>>如下形式的矩阵

| id1 | id2 | score |
|-----|-----|-------|
| 1   | 3   | 95%   |
| 1   | 2   | 100%  |
| 1   | 4   | 85%   |
| 1   | 5   | 95%   |
| 2   | 10  | 80%   |
| 2   | 15  | 99%   |

我想按列对矩阵进行排序(首先使用分数,然后使用 id1)。我已经以排序方式获得了 id1。这意味着我还需要首先使用 score 对具有相同 id1 的所有记录进行排序,然后使用 id2 对所有记录进行排序。这样做的原因是在每个 id1 中创建 id2 的排名。上述示例的结果将是:

| q_id | d_id | rank | score |
|------|------|------|-------|
| 1    | 2    | 1    | 100%  |
| 1    | 3    | 2    | 95%   |
| 1    | 5    | 3    | 95%   |
| 1    | 4    | 4    | 85%   |
| 2    | 15   | 1    | 99%   |
| 2    | 10   | 2    | 80%   |

如何使用一些内置的集合方法在 Java 中实现这一点?

4

4 回答 4

1

我不确定你所描述的实际上是一个矩阵。在我看来,它就像一组三胞胎。

考虑为矩阵的每个“行”创建一个包装类:

class Triplet implements Comparable<Triplet> {
    private int id1;
    private int id2;
    private int score;

    // getters / setters here

    @Override
    int compareTo(Triplet that) {
        // if I understood correctly, you want to sort by score, then id1, then id2.
        int result = this.score - that.getScore();
        if (result == 0) {
            result = this.id1 - that.getId1();
            if (result == 0) {
                result = this.id2 - that.getId2();
            }
        }

        return result;
    }
}

然后将您的“矩阵”表示为ArrayList<Triplet>并像往常一样进行排序。

于 2012-09-17T21:35:33.990 回答
1

创建一个包含每个 ArrayList 行的所有列/字段的对象。然后使用 Comparator 接口并使用 Collections.sort()。

您可以查看http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort%28java.util.List,%20java.util.Comparator%29

于 2012-09-17T21:24:18.680 回答
1

一个适当的 OO 解决方案是将其声明为

class Bucket {
    int val1;
    int val2;
    int percent;
}

List<Bucket> myList = ...

并提供一个Comparator以您想要的方式排序元素

于 2012-09-17T21:26:44.953 回答
0

首先,您最好将数据保存在普通旧 Java 对象 (POJO) 中,而不是整数列表列表中。

从您的示例中,您的数据似乎具有三个元素:两个 id 和一个分数。POJO 可能是这样的:

public class Record() {
    private int id1;
    private int id2;
    private double score; // percent, so double from 0.0 to 1.0

    public Record(int id1, int id2, double score) {
        this.id1=id1;
        this.id2=id2;
        this.score=score;
    }
    // getters and setters
}

然后,您只需拥有一个List<Record>.

根据我对您问题的了解,您想先按 id1 排序,然后按 id2 排序。那正确吗?这看起来需要基数排序(链接是维基百科)。

伪代码将是这样的:

  1. 循环遍历每条记录并将它们分类到“桶”中id1。每个“桶”可以是一个List<Record>,并且应该包含所有Record具有相同 id1 的对象,没有特定的顺序。
  2. 循环遍历每个存储桶并按id2.
  3. 将所有存储桶重新组合在一起,保持顺序。

您需要使用 和 之类的方法来更新对象Record,以便高效、干净地实现它。public int compareId1(Record other)public int compareId2(Record other)

于 2012-09-17T21:28:46.923 回答