Java传参、hashcode和equals重写应注意的原理

最近发现之前复习的java内容都好浅,不够深入,不够扎实。总是为了追赶进度。从今天开始每天会针对一个点认真深入学习。理解原理。

并且发现自己的表述能力太弱了,不能将自己内心的想法,正确的讲出来,所以以下内容以问答的方式进行,方便以后回头复习。

Q:java方法中参数传递是值传递还是引用传递?

A:在C++中存在值传递和引用传递,而在java中只存在值传递!首先值传递的概念是:将一个对象或者变量的值的一个副本作为参数传递给方法,在方法中对传入的这个参数的改变并不会影响原对象或变量的值。而引用传递的概念是变量或者对象自己本身的地址作为形参传入方法中,在方法中对这个传入的这个地址进行操作会影响到原对象或者变量的值。  在java中虽然将一些自定义的类的对象作为形参传入方法中看似在方法中对该变量进行修改会改变原变量的值,其实不然。比如下例:Student s=new Student();将s作为形参传入方法中,实际是将s的副本传入方法中,而并没有将s变量的地址作为形参传入。原因就是当你在方法中对s进行重新new操作或者改变s的值时,原s变量并没有改变。这里存在一个误区,将s传入方法实际是将你new的student对象的地址的拷贝传入了方法中,而对于s变量而言student对象的地址就是s变量的值,因此java中只存在值传递而。

Q:重写HashCode方法应该注意哪些问题?

A:重写HashCode方法应该注意:1.如果两个对象的equals方法返回的结果为true,那么这两个对象的hashCode方法的返回值必须相同。2.如果两个对象的equals方法返回的结果为false,那么这两个对象的hashCode的值可以相同也可以不相同,但是最好是不相等的两个对象的hashcode 的值不相等,这在哈希表中的效率会好很多。3.如果在同一个应用程序中两个对象在equals中没有做任何的修改那么这两个对象的HashCode返回的值也不变,在两个应用程序中则不严格要求。

Q:重写equals应该注意哪些问题?

A:除了上面所说的HashCode方法注意的问题之外。还应该注意一下原则:1.自反性原则:一个对象自己equals自己结果为true,x.equals x为true;2.对称性原则:如果x.equals y为true,那么y.equalsx也为true;3.传递性原则:如果x、y、z中x.equals y ,y.equals z 那么x.equals z。4.非空性原则:对于任何一个非空的对象 x.equals(NULL)其结果为false。5.一致性原则:对于任何两个非空对象x,y在不进行修改的前提下它们两个的equals返回的值也不会变。

Q:了解String中的HashCode实现吗?为什么要使用31来作为每次乘积的跌带?

A:String中的HashCode的实现:将h=h*31+s[i]这个表达式循环它内部封装的value数组长度次。实际的hash=s[0]*31^(n-1)+s[1]*31^(n-2)+...+s[n-1]。

至于为什么会使用31,因为为了得到足够散列的hash值,使它们的冲突达到最小,因此不能选取太小的数字进行每次的跌带乘积,因为太小的数字得到的hash值太小,使hash原本32bit的数据位无法使用到高位数据位,这样得到的散列冲突会很多。当然也不能选取过大的数字来进行乘积,原因hash返回的是int类型,由于太大的数字会很容易使int类型产生溢出,产生数据丢失严重。而为什么要使用质数呢,原因在于选择偶数会在乘法运算中产生溢出,因为乘以2相当于右移一位。至于为什么会选择31呢,原因在于31*N会在JVM运行时进行优化,会优化成(N<<5)-N。由位移运算符和减法进行计算,来获得更好的性能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值