【问题标题】:Does ArrayList use the hashCode method of added objects when adding themArrayList 添加对象时是否使用添加对象的 hashCode 方法
【发布时间】:2014-05-04 04:31:27
【问题描述】:

以下代码是否使用了我的Scooter 类的hashCode 方法:

void using_ArrayList(){
        List coll=new ArrayList();

        Scooter s1=new Scooter();
        s1.setNumber("HR26KC345352344");
        s1.setHorse_power(123.321);
        s1.setYear_of_made(1997);

        Scooter s2=new Scooter();
        s2.setNumber("HR26KC34535");
        s2.setHorse_power(123.321);
        s2.setYear_of_made(1997);

        Scooter s3=new Scooter();
        s3.setNumber("HR26KC345352344");
        s3.setHorse_power(123.321);
        s3.setYear_of_made(1997);

        coll.add(s1);
        coll.add(s2);
        coll.add(s3);

        Scooter s=new Scooter();
        s.setNumber("HR26KC345352344");
        System.out.println(coll.contains(s));
}

滑板车类:

class Scooter{
    private String number;
    private double horse_power;
    private int year_of_made;
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public double getHorse_power() {
        return horse_power;
    }
    public void setHorse_power(double horse_power) {
        this.horse_power = horse_power;
    }
    public int getYear_of_made() {
        return year_of_made;
    }
    public void setYear_of_made(int year_of_made) {
        this.year_of_made = year_of_made;
    }

    public boolean equals(Object o){
        if((o instanceof Scooter)&&((Scooter)o).getNumber()==this.getNumber()){
            System.out.println("EQUALS:TRUE"); //OK
            return true;
        }
        else{
            System.out.println("EQUALS:FALSE"); //OK
            return false;
        }
    }

    public int hashCode(){
        System.out.println("HASHCODE");// NOT able To reach here...
        return number.length();
    }

}

我可以使用equals() 方法。但无法达到hashCode() 方法。 hashCode() 方法是否未被 ArrayList 集合使用?请告诉我,因为我是 Java-Collections 的新手。

【问题讨论】:

  • 您可以查看ArrayList的源代码并得到您自己的答案。
  • 请注意,通常基于哈希的集合的名称中会包含单词 hash。但就像@LuiggiMendoza 建议的那样,您可以通过自己查看源代码来确定。

标签: java arraylist hashcode


【解决方案1】:

与 HashMap 不同,ArrayList 不需要使用 hashCode() 方法,因为 ArrayList 中元素的顺序是由它们插入的顺序决定的,而不是由散列决定的。

【讨论】:

  • 明白。谢谢你:)
  • 呃……这个解释不合逻辑。明显的反例是LinkedHashMap,其中元素的顺序由插入顺序确定,并且当您调用addcontains 时使用hashCode()
  • LinkedHashMap 实际上有两种获取数据的方式:一种是通过哈希表,另一种是通过链表。只有链表按插入顺序排序;哈希表仍然需要哈希。
【解决方案2】:

ArrayList 集合不使用 hashCode() 方法吗?

我假设您的意思是ArrayList 元素的hashCode() 方法。 唯一元素hashCode()方法被ArrayList对象调用的情况是在计算ArrayList本身的哈希码时。

您可以通过查看源代码或阅读 javadocs 来确认这一点。 (行为在List API 中指定并在AbstractList 中实现...)


因此,预计您不会在示例中看到来自List.addList.contains 的对hashCode() 的调用。特别是,contains 对每个调用equals 的列表元素进行迭代,直到调用返回trueArrayList 的实现并没有使contains 快速运行。


我还要指出this answer中给出的解释是不正确的:

“与HashMap 不同,ArrayList 不需要使用hashCode() 方法因为ArrayList 中元素的顺序由它们所在的顺序决定插入,而不是通过散列。”

这在几个方面是不正确的:

  1. ArrayList 的顺序不是由添加元素的顺序决定的。它由添加(和其他操作)的顺序和位置决定。

  2. HashMap 中使用hashCode 的原因不是为了确定订单。 (事实上​​,HashMap 的顺序是荒谬的......对于第一个近似值。)散列(通过 hashCode)实际上用于提供 O(1) 按键查找。

  3. LinkedHashMap 是上述推理的反例。它保留插入顺序并使用hashCode

事实上,这两个问题(元素顺序和散列的使用)是正交的。 hashCode() 不用于在ArrayList 中查找的实际原因更务实:

  • 添加类似哈希表的数据结构将使ArrayList 的内存开销增加每个元素至少 5 倍,甚至可能更多。

  • 在同一数据结构中实现基于元素值的O(1)基于哈希的查找(对于contains)和基于元素位置的O(1)查找(对于get)非常复杂。

ArrayList 旨在为部分用例提供内存和时间效率。在这些用例中,散列会成为一个障碍。但无论哪种方式,它使用它。

【讨论】:

    【解决方案3】:

    从您的代码中可以明显看出,它不使用 hashCode。此方法用于哈希,而不是像 ArrayList 这样的线性集合。并且在 O(N) 中执行搜索

    【讨论】:

    • 明白。谢谢你:-)
    【解决方案4】:

    哈希码仅用于那些需要识别唯一值的集合。

    所以它用于 Set 类型的集合。

    允许在数组列表中重复,因此没有检查哈希码的概念。

    【讨论】:

    • 嗨,hashmap 如果你正确查看它的 api,它清楚地表明键应该是唯一的,并且 hashmap 键再次只是一个集合..所以它使用哈希码......当你做 map.keySet( ),您设置的不是列表..正确地通过 hashmap 键。和 set 一样。
    • 如果 Treeset 不使用 hashcode ,如果我添加 treemap.add(1) 和 treemap.add(1) 会发生什么,它是否允许重复,如果没有 equals 和 hashcode 如何管理?
    • 是的,HashMaps 使用唯一键,但这并不意味着 hashCode() 仅用于与 Set 相关的集合。例如,IdentityHashMap 可以接受“重复”键(equals() 返回 true 的键)。 hashCode() 旨在作为一种工具,允许Hash-相关集合正常运行,并不意味着特定用途。
    • TreeMap 实例使用ComparatorscompareTo() 对象的compareTo() 方法来放置条目。它根本不使用hashCode()
    • ha 并阅读我的第一行,这正是我所说的“哈希码仅用于那些需要识别唯一值的集合”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    相关资源
    最近更新 更多