【问题标题】:Issue With Value Comparison in Sort排序中的值比较问题
【发布时间】:2013-04-24 22:26:29
【问题描述】:

我在一个单独的 .java 文件中使用 ArrayList 类方法等,因为我继续致力于高分功能。现在,安排两个相等的分数符合我的目的,使得分数 n 的第一个实例(如果它是第一个分数,则在它之前不等于)在列表中保持高于分数 n 的第二个实例。我已经使用了两种排序方法,但它总是跳过我尝试使用 == 比较的循环的任何部分。我正在手动设置值“测试”(参见代码)。代码如下,如果有任何似乎难以理解的地方,请随时提及。调试的东西被注释掉了。

import java.util.*;

   public class arraylisttest 
   {    
        public static void main(String[] args)
    {
    ArrayList<Integer> grn = new ArrayList<Integer>();
    System.out.println("Empty:");
    for (int i = 0; i < grn.size(); i++)
    {
        System.out.println("Key" + i + " : " + grn.get(i));
    }
    grn.add(122);
    grn.add(534);
    grn.add(132);
    grn.add(310);
    grn.add(267);
    grn.add(322);
    System.out.println("Full:");
    for (int i = 0; i < grn.size(); i++)
    {
        System.out.println("Key" + i + " : " + grn.get(i));
    }
    int myscore = 534;
    Integer test = myscore;//reassignment, not entirely necessary
    int y = 0;
    Collections.sort(grn);

    System.out.println("Sorted: ");
    for (int i = 0; i < grn.size(); i++)
    {
        System.out.println("Key" + i + " : " + grn.get(i));
    }

    //fix sort so that number is added correctly if equal to last element
    int max = grn.size();

    if(test > grn.get(y))
    {
        if(test < grn.get(max - 1))
        {
            System.out.println("bigger, sm max");
            grn.set(y, test);//in at 0
            y++;//now 1
            while (grn.get(y) < test)
            {
                grn.set(y-1, grn.get(y));//shift this one down
                grn.set(y, test);//fill the hole
                y++;//ends up at 5
            }
        }

        else if(test > grn.get(max-1))
        {
            System.out.println("bigger, gr max");
            int temp = grn.get(max-1);
            grn.set(max-1, test);//in at end
            y++;
            while(y < (max-1))
            {
                grn.set(y-1, grn.get(y));//shift this one down
                grn.set(y, grn.get(y+1));//fill the hole
                y++;//ends up at 5
            }
            grn.set(max-2, temp);
        }

        else if(test == grn.get(max-1))//error here
        {
            System.out.println("bigger, eq max");
            y++;//now 1
            while (grn.get(y) < test)
            {
                grn.set(y-1, grn.get(y));
                grn.set(y, test);
                y++;
            }
            grn.set(y-1, test);
        }

        else
        {
            System.out.println("Oops.");
        }
    }
    else
    {
        System.out.println("too small");
    }
    //end sort

    //System.out.println("Test: " + test);
    //System.out.println("Myscore: " +myscore);

    System.out.println("Sort" + y + " : ");
    for (int i = 0; i < grn.size(); i++)
    {
        System.out.println("Key" + i + " : " + grn.get(i));
    }

请注意,据我所知,前两种按预期工作。

【问题讨论】:

  • 你想完成什么?可能有比您正在尝试的更好的方法。

标签: java sorting arraylist conditional


【解决方案1】:

我认为您尝试手动进行排序的原因是您想确保在出现平局的情况下,首先获得分数的人将被列在第一位。有一种更好的方法 - 将数据存储在自定义对象中,并将Collections.sort() 与比较器一起使用。

例如:

public class HighScore {
    public int score
    public String name
    public long timestamp

    public HighScore(int score, String name, long timestamp) {
        this.score = score;
        this.name = name;
        this.timestamp = timestamp;
    }
}

创建时,使用System.currentTimeMillis() 获取时间戳。然后当你对它们进行排序时,使用这个:

Collections.sort(grn, new Comparator<HighScore>() {
    @Override
    public int compare(Highscore h1, Highscore h2) {
        if (h1.score == h2.score) {
            return h1.timestamp < h2.timestamp ? -1 : 1;
        } else {
            return h2.score - h1.score;
        }
    });

这样你只需要调用grn.add(),然后调用Collections.sort()

【讨论】:

  • 另外,我不确定我的比较方法是否正确,但您应该能够理解总体思路
【解决方案2】:

equals 测试的默认实现是针对身份而不是针对相等(实际上,“什么构成对象的相等?”这个问题的答案可能会变成一个相当复杂的讨论),即定义了 objecta.equals(objectb)默认情况下为 objecta == objectb,仅当它们引用完全相同的实例时才为 true。

Strings 可以直接与 sa.equals(sb) 进行比较的原因是因为提供了 equals() 的实现,当字符序列相同时建立相等性。永远不会为您滚动的类提供 equals() 的实现。

这意味着当您决定在 Collections 框架中使用自己的对象,然后使用依赖于 equals() 实现的特性或方法时,您会遇到问题,因为 a==b 几乎从来都不是你想要的。

TL;DR:要充分利用 Collections Framework 与您自己的对象,您必须定义和实现 equals()、hashcode(),通常还有 Comparable 接口。

【讨论】:

    【解决方案3】:

    如上所述,类与 .equals() 函数进行比较,您的测试变量显然不是原始类型...

    【讨论】:

      【解决方案4】:

      在java中Integer是一个类。要比较两个对象的值,您需要使用.equals,否则您将比较它们是否是同一个对象(这意味着内存中的引用相同)。

      【讨论】:

      • :3 我对 String 对象提出了同样的问题,并有一种错误的印象,我可以通过这种方式比较整数。现在可以了,谢谢。
      • @Antidiscrete 您可以投票并接受答案:) 很高兴为您提供帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多