hashCode与for-each

/*当使用for-each循环时,对每个取出的元素进行操作并不会影响原数据:
*        Integer[] a = {1,2,3};
        for(Integer aa: a){
            aa = 0;
        }
        System.out.println(Arrays.toString(a));//输出[1,2,3]
 */

起因是想练习一下重写hashCode(), 然后和编译器自动重写的hashCode返回值做对比

原预计本该输出相同值,却未达到预期

public class Late_Test {
    public static void main(String[] args) {
        MyDate date = new MyDate(1, 2);
        System.out.println(date.hashCode());
        System.out.println(date.hashCode1());
    }
}

class MyDate {
    private int year;
    private int month;
    String name;

    public MyDate(int year, int month) {
        this.year = year;
        this.month = month;
    }

   
    public int hashCode1() {
        int result = 1;
        Integer i = Integer.valueOf(year);
        Integer ii = Integer.valueOf(month);
        result += 31 * result + (i == null ? 0 : i.hashCode());
        result += 31 * result + (ii == null ? 0 : i.hashCode());
        return result;
    }
    @Override
    public int hashCode() {
        return Objects.hash(year, month);
    }
}

分析

给出的year和month值都在cache数组范围里,所以hashCode1()得到的对象 i 应该和 hashCode()里传给hash()的参数是同一个对象(存在自动装箱),同样的 ii 也是一样

经过debug发现的确如此

但是问题出在hash()里

public static int hash(Object... values) {
    return Arrays.hashCode(values);
}
public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)//出问题的地方
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

如上所言,for-each遍历a[],并不是单纯使用指针指向a[]中的元素,似乎是重新new了对象,导致element.hashCode()返回了不一样的值,得出了不同于hashCode1()的result值

另外,虽然以前就已经注意到过,但还是在这里进行强调

像Integer和int这样具有自动装箱拆箱特性的类型,在作为函数参数的时候也会体现,即上述程序调用hash()的表现

但是要注意一种特殊情况,int和Integer不是在任何情况下都可以做到兼容的

Integer[] a = {1,2};
int[] aa = {new Integer(3)};
a = aa;//error
a[0] = aa[00];//right ,自动拆箱
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值