使用Hashcode对对象的ArrayList进行排序

时间:2012-03-14 15:05:17

标签: java sorting collections arraylist hashcode

我有一个对象的ArrayList(POJO),它有一个Id和另一个字段。我已经在Id字段的POJO中实现了equals()/ hashcode()覆盖。当我使用Object类的equals()方法比较两个对象时,它完全正常。但是,当我将这些对象添加到arraylist并实现

Collections.sort(arrListOfObjects);

它给了我一个classCastexception。我抬起头,发现我需要实现一个比较器。这个比较器也做了等于/ hashcode覆盖的东西。如果是这样那么为什么上面的代码不起作用?(我知道没有比较器,但我的问题是,是否不可能基于对象的哈希码实现排序?)

5 个答案:

答案 0 :(得分:6)

如消息所示,您的对象需要实现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());
    }
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

public int hashCode() {
     return 1;
}

鉴于这个hashCode方法与使用此方法定义的Comparator串联,几乎可以肯定列表无法正确排序,除非有琐碎的情况(空列表,单个元素列表等)。

一般来说,要记住的一件好事是java.lang.Object.hashCode java doc中记录的hashCode-equals契约。简而言之,hashCode碰撞可能会导致不对等的对象,使得在这些方法上定义的排序无效。

答案 3 :(得分:0)

随着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()));
}

答案 4 :(得分:0)

如果使用Java 8,则可以通过以下方式进行定义:

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

此方法不需要Pojo实现Comparable接口。