【问题标题】:Java Comparable issue [duplicate]Java可比问题[重复]
【发布时间】:2013-05-13 14:22:11
【问题描述】:

我想按对象拥有的字符串对对象进行排序。只是想知道这有意义吗? 之前我只用过Arrays.sort(BlahList); 但现在我可以有很多对象,而不仅仅是一个字符串数组列表。

public class Contact implements Comparable
{
    private string name;

    public compareTo (Contact Contact1)
    {
        return this.name.compareTo(Contact1.name);
    }
}

在我的主要方法中:

Collections.sort(ContactList);

我还想知道如果名称是年龄,这是否适用于整数?

【问题讨论】:

  • 使用age-contact1.age 表示整数(请不要以大写开头你的变量名)。
  • 你的问题真的不清楚。你想按 int 还是 string 排序?
  • 当您尝试编译和运行此代码时会发生什么?提示:Comparable 是通用的。你的班级应该实现Comparable<Contact>
  • 对不起!我的意思是像 int 年龄这样的年龄,我将如何按它而不是字符串进行排序.. 是不是一样的方式?

标签: java


【解决方案1】:

首先,你应该输入Comparable接口:

public class Contact implements Comparable<Contact>

其次,您应该为参数/变量使用前导小写:

public compareTo (Contact contact)

第三,除非必要,否则不要使用this. - 这只是代码混乱:

return name.compareTo(contact.name);

最后,是的,你可以这样比较年龄:

return age - contact.age; // order youngest to oldest

或者更简洁的方式(感谢 JB 指出这一点):

return Integer.compareTo(age, contact.age);

整个班级应该是这样的:

public class Contact implements Comparable<Contact> {
    private string name;

    public int compareTo(Contact contact) {
        return name.compareTo(contact.name);
    }
}

注意:您的 compareTo() 方法的代码中缺少返回类型 int

要改为比较年龄,请将 compareTo() 方法替换为:

public int compareTo(Contact contact) {
    return Integer.compareTo(age, contact.age);
}

【讨论】:

  • 对于无论其值是多少都有效的 int 比较,您应该更喜欢 Integer.compare(i1, i2)(这也更清楚)
  • 顺便说一句,当age 大约是 Integer.MAX_VALUE 或/和contact.age 大约是 Integer.MIN_VALUE 时,减号运算符可能无法正常工作。当然,多年来并非如此。我推荐使用Integer.compare (Java7)
  • @RiaD 我并不特别关心它是否会在名称上引发 NPE:此代码更多用于说明而非生产用途。
  • @RiaD 你严重的鼻子年龄接近 MIN/MAX int 吗?因为那太疯狂了。我们在这里讨论的是people——这个类叫做“Contact”。我很确定年龄不会超过 100 岁左右。这是我见过的最荒谬的反对意见。
  • 这就是为什么我要补充说它不是多年来的情况(至少它们永远不会是负面的),但我想知道这个问题是可能的很好,尤其是当它很容易的时候避免它。 (只有一个标准功能)。我确定你知道。但并非所有阅读您的答案的人。可以开始以这种方式对任何整数进行排序。希望没有伤害到你
【解决方案2】:

它适用于所有人。如果是 int 则需要在 compareTo 方法中编写以下代码

return this.age-contact1.age// for ascending order contact1.age-this.age // for descending order

【讨论】:

    【解决方案3】:

    在 java 7 中,您可以使用 Integer.compare(age, contact.age)。 它(几乎)与 (x

    顺便说一句。不要使用 age-contact.age,因为 Integer.MIN_VALUE-Integer.MAX_VALUE = 1

    对于复杂的比较器(例如,首先按名称,然后按年龄,如果名称相同)我建议使用一些库,如 google guava。

    【讨论】:

      【解决方案4】:

      如果你想要多个比较器,那么我建议你使用Comparator 接口:

      名称比较:

      public class NameCompare implements Comparator<Contact> {
      
          @Override
          public int compare(Contact a, Contact b) {
              if (a.getName().compareToIgnoreCase(b.getName())>0)
                  return 1;
              else if (a.getName().compareToIgnoreCase(b.getName())<0)
                  return -1;
              return 0;
          }
      } 
      

      年龄比较:

      public class AgeCompare implements Comparator<Contact> {
      
              @Override
              public int compare(Contact a, Contact b) {
                  if (a.getAge() > b.getAge())
                      return 1;
                  else if (a.getAge() < b.getAge())
                      return -1;
                  return 0;
              }
          } 
      

      总的来说,您只需传递所需的Comparator

      ArrayList al = new ArrayList<Contact>
      
      Collections.sort(al, new NameCompare())
      
      Collections.sort(al, new AgeCompare())
      

      【讨论】:

      • 为什么你曾经两次调用函数并做一些 if's 即使当你想要函数返回值时:)
      • @RiaD,你是什么意思?
      • 您可以在第一种情况下返回a.getName().compareToIgnoreCase(b.getName());。干净多了
      • @RiaD,我返回 1,-1,0 的原因是因为如果你想颠倒顺序很容易。因为它清楚地告诉您返回的是什么顺序 asc/desc。有时,更多的代码意味着更清晰:)
      猜你喜欢
      • 2011-05-05
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-23
      • 2011-03-21
      相关资源
      最近更新 更多