【问题标题】:Sorting 2D array String with number fields使用数字字段对二维数组字符串进行排序
【发布时间】:2012-12-17 09:25:02
【问题描述】:

我想很多人都遇到过这个问题, 您有一个由字符串分量和整数组成的二维数组。 例如。

    `String[][] data = {{"Name1","5"}, {"Name2","10"},{"Name3","1"}, {"Name4","3"}};`

现在您想按整数(在本例中为球员得分)对该二维数组进行排序,但是您希望匹配的名称与球员得分一起移动。 这就是我所拥有的,但结果与想象的相差甚远。

    private void sort(){
    boolean sort;
    int current, next;
    do{
            sort = true;
            for (int i = 0; i < data.length - 1; i++){
                if (data[i][1] !=null && data[i+1][1] != null){
                    current = Integer.parseInt(data[i][1]);
                    next = Integer.parseInt(data[i+1][1]);
                        if(current > next){
                                String temp = "";
                                data[i][1] = Integer.toString(next); 
                                data[i+1][1] = Integer.toString(current);
                                data[i][0] = temp;
                                data[i][0] = data[i+1][1];
                                data[i+1][0] = temp;       
                                sort = false;
                        }
                }

            }

    }while(!sort);
}

如果你问为什么人们会使用一个普通的二维数组,那是因为在 JFRAME 中,一个 JTable 需要一个二维数组来存储数据。

【问题讨论】:

  • 看我的回答:虽然不够通用,但它可以提供后见之明。本质上,您的数组元素需要能够相互比较?

标签: java string sorting multidimensional-array integer


【解决方案1】:

您可以编写一个特殊的比较器,它可以比较例如 {"Name1","5"}{"Name2","10"} 但我建议更改您的数据结构。

我会创建一个包含 nameint

的类型
class NameNum{
   String name;
   int number;
}

并将它们存储在一维数组中

NameNum[] data 

实现一个比较方法,而不是简单地使用Arrays.sort(..) 对数组进行排序。

【讨论】:

  • 当你在做的时候,为什么不让NameNum 类自己实现Comparable 呢?它将允许使用一些非常方便的集合原语;)
  • 好吧,在这种情况下实现Comparable 看起来是个好主意,因为您可以使用SortedSet 来充分发挥作用,请参阅我的回答。
  • 除了创建一个新类之外,您还可以维护一个 Map"nameN" 字符串映射到 int(或带 w/e 的 int 字符串)并使用它。在我看来,这似乎更合适。
  • @A.R.S.这将是一个解决方案,但它并没有考虑到两个不同名字的玩家可以有相同的分数
  • A MapSet 只能使用,如果每个 Key / Entry 都是唯一的,我们从问题中给出的 rge 描述中不知道。
【解决方案2】:

首先:你的数组元素由一个字符串和一个整数组成,因为在:

{ "Name1", "5" }

"5" 不是Integer,而是String

假设你不关心相等性,这里的解决方案是在这个元组上创建一个包装器对象,使其实现自身的Comparable,并使用SortedSet。您必须将其反转才能显示,幸运的是 JDK 也为此提供了内置方法。

示例代码:

private static final String[][] data = {
    { "Name1", "5" },
    { "Name2", "10" },
    { "Name3", "1" },
    { "Name4", "3" }
};

private static final class Score
    implements Comparable<Score>
{
    private final String name;
    private final int score;

    private Score(final String name, final String scoreAsString)
    {
        this.name = name;
        // NOTE: this can throw an (unchecked) NumberFormatException,
        // but this code assumes that it never does
        score = Integer.parseInt(scoreAsString);
    }

    @Override
    public int compareTo(final Score o)
    {
        final int ret = score - o.score;
        return ret != 0 ? ret : name.compareTo(o.name);
    }

    // Print results nicely ;)
    @Override
    public String toString()
    {
        return "Name: " + name + ", score: " + score;
    }
}

public static void main(final String... args)
{
    final SortedSet<Score> set = new TreeSet<Score>();
    Score score;

    for (final String[] raw: data) {
        score = new Score(raw[0], raw[1]);
        set.add(score);
    }

    // Build a List from that Set...
    final List<Score> scoreList = new ArrayList<Score>(set);

    // Reverse it...
    Collections.reverse(scoreList);

    // Print results
    for (final Score s: scoreList)
        System.out.println(s);
}

将上面的代码复制/粘贴到一个类中,运行它:你会看到它完成了预期的工作。

重要提示:是的,这个自定义类不会覆盖equals()/hashCode();这不是疏忽:因为这里只需要比较(因为使用了SortedSet),所以根本没有理由实施它们。

【讨论】:

  • 因为一个玩家可以多次玩游戏,他不会是唯一的。
  • 好吧,代码在这种情况下同样可以正常工作,比较只会返回 0 ;) 已编辑...
猜你喜欢
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 2011-07-01
  • 2021-08-16
  • 2014-08-10
相关资源
最近更新 更多