【问题标题】:Sorting ArrayList of Objects using Hashcode使用哈希码对对象的 ArrayList 进行排序
【发布时间】:2012-03-31 01:33:53
【问题描述】:

我有一个包含 Id 和另一个字段的对象 (POJO) 的 ArrayList。我已经在 POJO 中为 Id 字段实现了 equals()/hashcode() 覆盖。当我使用 Object 类的 equals() 方法比较两个对象时,它工作得非常好。但是,当我将这些对象添加到数组列表并实现

Collections.sort(arrListOfObjects);

它给了我一个classCastexception。查了一下,发现需要实现一个Comparator。这个比较器也对等于/哈希码覆盖做了一些事情。如果是这样,那么为什么上面的代码不起作用?(我知道没有比较器,但我的问题是,不能根据对象的哈希码实现排序吗?)

【问题讨论】:

  • 您肯定希望实现 Comparable 接口。 compareTo() 方法实际上是确定某事物是“大于”还是“小于”另一事物。 equals() 方法只能判断某些东西是否“相等”,这对订购没有多大作用。

标签: java sorting collections arraylist hashcode


【解决方案1】:

如果 java 8 是一个选项,您可以这样定义:

list.stream().sorted(Comparator.comparing(Pojo::hashCode));

这种方式不需要Pojo实现Comparable接口。

【讨论】:

    【解决方案2】:

    随着 Java8 或更高版本的出现,我将使用 lambda 表达式实现 Comparator;

    public static void main(String[] args) {
        List<String> list = Arrays.asList("string", "sdkj");
        list.forEach(s -> System.out.println(s + "=" + s.hashCode()));
    
        Collections.sort(list, (o1, o2) -> (o1.hashCode() - o2.hashCode()));
    
        System.out.println("After Sorting");
    
        list.forEach(s -> System.out.println(s + "=" + s.hashCode()));
    }
    

    【讨论】:

      【解决方案3】:

      Comparator 不对equals 或hashcode 做任何事情,它使用equals 或hashcode 来确定它返回的内容。它是Collections.sort 方法文档的一部分。看一看 Comparable 接口并在你的类中实现它。例如,您可以查看 SO Question java class implements comparable

      【讨论】:

        【解决方案4】:

        实现基于哈希码的排序当然是可能的,但可能不会始终如一地产生所需的行为。例如,考虑一个类Foo,其hashCode() 方法被定义为始终返回一个常量值。例如:

        public int hashCode() {
             return 1;
        }
        

        鉴于此 hashCode 方法与使用此方法定义的 Comparator 串联,列表几乎肯定不会正确排序,除非是琐碎的情况(空列表、单元素列表等)。

        一般来说,要记住的一件好事是java.lang.Object.hashCode java 文档中记录的 hashCode-equals 合同。简而言之,对于不相等的对象,可能会导致 hashCode 冲突,从而导致在这些方法上定义的排序无效。

        【讨论】:

          【解决方案5】:

          如消息所述,您的对象需要实现 Comparable 接口才能进行排序。或者,您可以为您的sort() 方法提供一个比较器。例如,假设您的对象是字符串并且您想根据哈希码进行排序,您可以这样做:

          public static void main(String[] args) {
              List<String> list = Arrays.asList("string", "sdkj");
              for (String s : list) {
                  System.out.println(s + "=" + s.hashCode());
              }
              Collections.sort(list, new Comparator<String>() {
          
                  @Override
                  public int compare(String o1, String o2) {
                      return o1.hashCode() - o2.hashCode();
                  }
              });
              System.out.println("After Sorting");
              for (String s : list) {
                  System.out.println(s + "=" + s.hashCode());
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-10-23
            • 2015-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-15
            • 1970-01-01
            • 1970-01-01
            • 2019-11-24
            • 2012-05-01
            相关资源
            最近更新 更多