基础知识-HashMap知识点

 2024-01-24 00:02:09  阅读 0

key值为null时访问

我们知道插入元素的key值是允许为null的。 我们看一下这部分的源码:java

private V putForNullKey(V value) {
    for (Entry e = table[0]; e != null; e = e.next) {
        if (e.key == null) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(0, null, value, 0);
    return null;
}

可以看到,当key=null时,对应的数据存储在链表中内部数组的第一个位置。 知道了它是怎么保存的,那么获取就简单了:在内部数组的第一个位置编译列表,找到key=null的数据项,返回数据项中的值。

private V getForNullKey() {
    for (Entry e = table[0]; e != null; e = e.next) {
        if (e.key == null)
            return e.value;
    }
    return null;
}

和方法

在之前的博文:《基础知识-》原理分析中,我们可以知道key必须实现它的sum方法,两者缺一不可。但是大家知道,这两个方法默认都是从对象继承的。 我们看一下原生的实现:数组

public native int hashCode();
public boolean equals(Object obj) {
    return (this == obj);
}

可以看到,该方法使用关键字表明其实现是调用C/C++的底层函数来实现,并且该方法认为只有当两个对象的引用指向同一个对象时,才认为是equal.

如果你自定义一个类,并且不重写方法和方法,并且使用这个类的对象作为键值来保存,那么在读取的时候,除非你使用了和保存时一模一样的引用,否则该对象用作key值,否则永远得不到key对应的value。 IDE

下面是一个很好的 sum 实现的例子:

public final class PhoneNumber {
    private final short areaCode;
    private final short prefix;
    private final short lineNumber;
    public PhoneNumber(int areaCode, int prefix,
                       int lineNumber) {
        this.areaCode  = (short) areaCode;
        this.prefix  = (short) prefix;
        this.lineNumber = (short) lineNumber;
    }
    @Override 
    public boolean equals(Object o) {
        if (o == null)
            return false;
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber)o;
        return pn.lineNumber == lineNumber
            && pn.prefix  == prefix
            && pn.areaCode  == areaCode;
    }
    @Override 
    public int hashCode() {
        int result = 17;
        result = 31 * result + areaCode;
        result = 31 * result + prefix;
        result = 31 * result + lineNumber;
        return result;
    }
}

函数方法怎么封装_c hashmap 方法函数_函数方法有哪些

实施建议如下:

表现

1. 将一个非零常量值,例如17,保存在一个名为int类型的变量中。

2、对于对象中的每个关键域f(指方法中涉及到的每个域),完成以下步骤:

A。 计算该字段的int类型的哈希码c:

我。 如果该字段是类型,则计算 (f?1:0)。

c hashmap 方法函数_函数方法怎么封装_函数方法有哪些

二. 如果字段的类型为 byte、char、short 或 int,则计算 (int)f。

三. 如果字段是long类型,则计算(int)(f^(f>>>32))。

四. 如果字段为float类型,则计算Float.(f)。

v. 如果该字段是类型,则计算.(f),然后按照步骤2.a.iii计算得到的long类型值的哈希值。

六. 如果该字段是一个对象引用,并且递归调用该类的方法来比较该字段,那么也会针对该字段递归调用该方法。 如果需要更复杂的比较,请计算该字段的范式 ( ),然后针对该范式调用它。 如果该字段的值为空,则返回0(也可以接受其他常量)。

七. 如果字段是数组,则每个元素必须被视为单独的字段。 即递归地应用上述规则,为每个重要元素计算一个哈希码,然后根据步骤2.b中的方法组合这些哈希值。 如果数组字段中的每个元素都很重要,您可以使用版本 1.5 中添加的方法之一。

b. 根据以下公式,将步骤2.a计算出的哈希码c合并为: = 31 * + c; //这里31是一个奇素数,而且它有一个非常好的特性,就是用移位位和减法代替乘法可以达到更好的性能:31*i == (i

标签: 数组 引用 调用

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码