java 基础篇 i++ / % "=="equals hashcode

一 i++ 和 ++ i 深入分析

两种方式均为自增,不同点在于  i++ 是在先参与运算后再加1,而++i 则是先加1,再参与运算

示例1 

public class Test{

 public static void main(String [] args){

  int i = 1;

  int s = ++i;//先把i+1 然后赋值给了s

  int x= i++;//先把i赋值给x,再把i+1

  System.out.printLn(i);

  System.out.printLn(s);

  System.out.printLn(x);

 }

}

输出结果为  3,2,2 

(  i++:是先把i拿出来使用,然后再+1;  ++i :是先把i+1,然后再拿出来使用;)

示例2 

int i=5;

int s=(i++)+(++i)+(i--)+(--i)=24;

输出结果  24

5 = (i++) //i先赋值给左边,i再加1   此时 i = 6
7 = (++i) // i先加1 再赋值给左边   此时 i= 7 
7 = (i--)  // i先赋值给左边,i再减1 此时 i= 6
5 = (--i) // i先减1  再赋值给左边,此时 i= 5

所以4个算式的结果相加 = 5+7+7+5 = 24 

示例3 

public class Test{

 public static void main(String [] args){
  int i = 1;
  System.out.printLn(i+++i++);
  System.out.printLn("i="+i);

  System.out.printLn(i+++++i);
  System.out.printLn("i="+i);

  System.out.printLn(i+++i+++i++);
  System.out.printLn("i="+i);
 }

}

程序运行结果 

3

i= 3

i= 5

18

i= 8

用括号分割计算即可 如第一个算式

int i = 1;
计算 (i++)+(i++)
int a = (i++); //i 先赋值给 a(此时a=1) i再加1 此时i=2
int b = (i++);
//i 先赋值给 b(此时b=2) i再加1 此时i=3
上列算式的和= a+b = 3

示例4 

int x = 1,y = 2,z = 3;
y+= z--/++x 表达式的值是() 

z-- 等于3  此时z = 2;

++x等于2  此时x= 2;

3/2 = 1 (除法运算符,结果向下取整)

y=y+1 = 3;

所以结果为3 

二  / 和 % 

运算符  /  :除法运算符,并且运算结果遵从向下取整。

    如 1/2 = 0;4/3 = 1;

运算符 % :模运算(即取余数)

      (1)、当运算符左边小于右边,结果就等于左边;

      (2)、当运算符左边大于右边,就和算术中的取余是一样的效果

如 1%2 = 1; 2%2 = 0;3%5 = 3;

三  "==",equals 和 hashCode

3.1  理解”==“的含义 

主要有两个作用 

   1、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样

   2、引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。

3.2 理解 equals() 的含义

如下图 看下 equals()的源码

 内部实现是用的 "==", 所以equals()比较的也是引用地址

到这里,好像发现 "=="和equals() 没什么区别,别急,继续往下看

3.3 重写equals()

1、String中equals()方法

从上面我们知道,发现 "=="和equals ()没什么区别,equals()好像没什么意义存在,因为都是比较的引用地址,

不过后来String重写了equals()方法,重写之后,String中的equals()方法其实比较的是字符串的内容是否一样。

2 测试 

boolean result =  "bba".equals(new String("bba"));

结果为true  比较的值内容

但  boolean result =  "bba" == new String("bba");

结果为false ,比较的引用地址("bba"存在常量池中,new String("bba") 这新对象存于堆中)

所以如果编写的类,希望能否比较该类创建的2个对象的内容是否相等,那么可以重写equals()方法,由开发人员来决定在什么情况下即认为2个对象的内容相等

如一个Person 类,是人名字相等代码2个对象内容相等,还是名字+身份证号相等,代表2个对象内容相等,由开发人员在重写equals()方法里决定。

3.4 hashCode()

        hashCode()方法是继承自Object类,返回对象在内存中地址转换(hash计算)成的1个int值,用来鉴定2个对象引用是否相等。虽然equals()方法也是用来判断2个对象是否相等的,但它区别于hashCode()。

        equals()方法是给用户调用的,判断2个对象是否相等,可以重写equals()方法,hashCode()方法,用户一般不会去调用它。

例如在hashMap中由于key是不可以重复的,在判断重复时就判断了hashCode()这个方法,也用到了equals()方法,

此处不重复,只要equals()和hashCode()有1个不等就可以了。hashcode()更像一个对象的ID编码,它与equals()不同之处在于它返回的是int型,比较起来不直观。

3.5  为什么说,在覆盖equals()方法的同时,要覆盖hashCode()方法?

        如果类覆盖了equals()方法,而不覆盖hashCode()方法会导致什么后果,我们实例说明

我们知道hashMap中要求key唯一,如果只覆盖了equals而没有覆盖hashCode, 则两个不同的instance a和b虽然equals结果(业务逻辑上)相等,但却会有不同的hashcode,

把这2个实例对象当做hashMap的key时候,会当做不同的key,这样hashMap里面会同时存在a和b两个key,而实际上我们需要hashMap里面只能保存其中一个,

因为从业务逻辑方向看它们是相等的。

hashCode()和equals()关系如下

1 a.equals(b) 返回true  那么调用a,b两个对象任意一个的hashCode()返回值都一样

2 a.equals(b) 返回false  调用a,b两个对象hashCode()值无要求,可相等可不等

3 调用a,b两个hashCode()值不相等,equals()也不相等

4 调用a,b两个hashCode()值相等,equals()可以不等

其实总结下来就是,equals()等,hashCode必须等,hashCode()等了,不要求equals相等不相等,因为hashCode()是散列算法,是会有概率相等的。

原文地址:https://www.cnblogs.com/hup666/p/12977936.html