2022.08.10 学习笔记

学习笔记

java

jdkjre

JDK是java开发工具包,提供了java的开发环境和运行环境

JRE是java的运行时环境,提供了java的运行环境

  • JDK包含了JRE,还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具。
  • 运行java -> 仅需JRE 编写java -> JDK

==equals的区别

  • ==对于基本类型来说是值比较,对于引用类型来说是比较的引用

  • equals默认情况下是引用比较,只是很多类都重写了equals方法,比如String Integer等 将其变成了值比较,所以一般情况下equals比较的是值是否相等

  //String中的equals方法    
  public boolean equals(Object anObject) {
          if (this == anObject) {
              return true;
          }
          if (anObject instanceof String) {
              String anotherString = (String)anObject;
              int n = value.length;
              if (n == anotherString.value.length) {
                  char v1[] = value;
                  char v2[] = anotherString.value;
                  int i = 0;
                  while (n-- != 0) {
                      if (v1[i] != v2[i])
                          return false;
                      i++;
                  }
                  return true;
              }
          }
          return false;
      }

hashCode()

hashCode()相同的,equals()不一定相同

例如,String的hashCode()计算方法:

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

执行以下代码,两者的hashCode()返回值是相等的

String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d",
str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));

PS:String.format()第一个参数是模式串,后面是依次传入的参数,返回值是用前面模式串替换了后面参数的字符串。模式串要替换的数据与C类似,这里%d是整数的意思,源码如下:

    public static String format(String format, Object... args) {
        return new Formatter().format(format, args).toString();
    }

把元素往set中添加时,首先会对比hashcode是否相等,如果hashcode不相等就直接往set中加这个元素,如果hashcode相等就对比equals方法,如果equals不相等就往set中加这个元素,所以set的元素重复性是根据hashcodeequals方法来判断的

同理,当我们自定义两个对象集合中的对象是否相等时,需要重写equalshashCode()方法:

public static void main(String[] args)  {
        Set<Person> personSet1 = new HashSet<>();
        Set<Person> personSet2 = new HashSet<>();
        personSet1.add(new Person(1,1));
        personSet1.add(new Person(2,1));
        personSet2.add(new Person(1,1));
        personSet2.add(new Person(1,2));
    //返回false
        System.out.println(personSet1.equals(personSet2));
    }

    static class Person{
        int age;
        int id;
        public Person(int age,int id){
            this.age = age;
            this.id = id;
        }
        @Override
        public boolean equals(Object o){
            if(!(o instanceof Person)){
                return false;
            }
            return age == ((Person) o).age && id == ((Person) o).id;
        }
        @Override
        public int hashCode(){
            return 0;
        }
    }

PS:常用hashCode()计算公式:

@Override
    public int hashCode() {
        //设置初始值
        int result = 17;

        //假设有效域为: name,age,idCardNo,incomeAnnual,sex,brithDay
        int c = 0;
        //计算name (String为对象类型,他的计算直接调用本身的hashCode)
        c = name.hashCode();
        result = result * 37 + c;

        //计算age (int/byte/char/short类型,他的计算直接调用本身的值)
        c = this.getAge();
        result = result * 37 + c;

        //计算idCardNo (long类型,他的计算 (int)(field^(field >>> 32)) 无符号右移32位)
        c = (int) (this.idCardNo ^ (this.idCardNo >>> 32));
        result = result * 37 + c;

        //计算 incomeAnnual (double类型,他的计算 Double.doubleToLongBits(field)后,再按Long类型计算 )
        //(float类型,他的计算 Float.floatToIntBits(field)  )
        long tmp = Double.doubleToLongBits(this.incomeAnnual);
        c = (int) (tmp ^ (tmp >>> 32));
        result = result * 37 + c;

        //计算 sex (sex为boolean类型,他的计算直接调用 c=sex?1:0)
        c = this.isSex() ? 1 : 0;
        result = result * 37 + c;

        //计算 brithDay (brithDay为Date对象类型,他的计算直接调用 本身的hashCode)
        c = this.getBirthDay().hashCode();
        result = result * 37 + c;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值