HashCode

HashCode

hashcode

/*哈希值:是一个十进制的整数,由系统随机给出(就是一个对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是实际地址)

  • 在object类中有一个方法,可以获得对象的哈希值
  • int hashcode()返回该对象的哈希值
  • hashcode方法的源码
  • public native int hashcode();
  • native:代表该方法调用的是本地操作系统的方法*/

新建一个对象类Person

代码:

public class Person extends Object {

}

测试类:

代码:

public class Demo01HashCode {
public static void main(String[] args) {
    Person p1=new Person();
    int h1=p1.hashCode();
    Person p2=new Person();
    int h2=p2.hashCode();
    System.out.println(h1);//1163157884,重写hashcode,放回值为一;
    System.out.println(h2);//1956725890,重写hashcode,放回值为一;
    System.out.println(p1);//cn.itcast.API.HashCode.Person@4554617c
    System.out.println(p2);//cn.itcast.API.HashCode.Person@74a14482
    System.out.println(p1==p2);//false
    /*String类的哈希值
    * String类重写object类的hashCode方法*/
    String s1=new String("abc");
    String s2=new String("abc");
    System.out.println(s1.hashCode());//96354
    System.out.println(s2.hashCode());//96354
    System.out.println("重地".hashCode());//1179395,巧合!
    System.out.println("通话".hashCode());//1179395
    System.out.println("你是谁:".hashCode());//631668296,一般情况!
    System.out.println("为了谁:".hashCode());//617023717
    HashSet<String> strings = new HashSet<>();
  //set存取hashcode相同的元素
    strings.add("abc");
    strings.add(s1);//地址值相同,且equals相同,不存储
    strings.add(s2);//地址值相同,且equals相同,不存储
    strings.add("重地");//地址值相同,但equals不相同,存储
    strings.add("通话");//地址值相同,但equals不相同,存储
    System.out.println(strings);//[重地, 通话, abc]
}

显示效果:

1163157884
1956725890
cn.itcast.API.HashCode.Person@4554617c
cn.itcast.API.HashCode.Person@74a14482
false
96354
96354
1179395
1179395
631668296
617023717
[重地, 通话, abc]

person类中的HashCode方法重写

代码:

public class Person extends Object {
    @Override
  public int hashCode()
{
      return 1;
}
}

测试类重写测试显示效果

1
1
cn.itcast.API.HashCode.Person@1
cn.itcast.API.HashCode.Person@1
false
96354
96354
1179395
1179395
631668296
617023717
[重地, 通话, abc]
重写HashCode后为什么P1和P2的返回值都是相同的p1 == p2还是false,因为p1 == p2比较的是两个实际地址值,而哈希值只是逻辑地址值,是模拟出来的地址

String s1=new String("abc");
    String s2=new String("abc");
    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s1==s2);//false

list存储数据先看两个字符串的哈希值是否相同再看是否Equals(值是否相同)再进行是否存入!
关于重地和通话哈希值相同为啥能够进入到set中,我们知道set不可以存储相同元素的,哈希值相同,我们还要看元素值equals是否相等,满足这两个条件才存储进set中

LinkedHashSet

哈希表和链表实现了Set接口,具有可预测的迭代次序。 这种实现不同于HashSet,它维持于所有条目的运行双向链表
代码:

public class LinkedHashSet {

public static void main(String[] args) {
    HashSet<String> set=new HashSet<>();
    set.add("www");
    set.add("baidu");
    set.add("www");
    set.add("com");
    System.out.println(set);
    java.util.LinkedHashSet<String> linked=new java.util.LinkedHashSet<>();
    linked.add("www");
    linked.add("baidu");
    linked.add("com");
    linked.add("baidu");
    System.out.println(linked);//按照原来的顺序,也不接受重复数据!
}
}

显示效果:

[com, www, baidu]
[www, baidu, com]

set存储对象时的应用

定义一个Student类存放对象的属性值
代码(已经重写了Equals和HashCode方法!,为了简便的观看重写了Tostring方法):

public class Student {
private String name;
private int age;

public Student() {
}

public Student(String name, int age) {
    this.name = name;
    this.age = age;
}

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return age == student.age &&
            Objects.equals(name, student.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}
}

测试类

代码:

public class StudentDemoTest {

public static void main(String[] args) {
    HashSet<Student> set=new HashSet<>();
    Student stu1=new Student("钱学森",22);
    Student stu2=new Student("钱学森",22);
    Student stu3=new Student("钱伟长",22);
    Student stu4=new Student("钱三强",22);
    System.out.println(stu1.hashCode());
    System.out.println(stu2.hashCode());//hashCode不一样,重写之后一样了!
    System.out.println(stu1==stu2);//false,地址值不一样
    System.out.println(stu1.equals(stu2));//false重写之后true
    set.add(stu1);
    set.add(stu2);
    set.add(stu3);
    set.add(stu4);
    System.out.println(set);
}
}

注意点

存储对象时,必须重写hashcode方法和equals方法!
重写tostring方法(非必须!将地址值的默认改掉!)

显示效果

1157313598
1157313598
false
true
[Student{name=‘钱三强’, age=22}, Student{name=‘钱伟长’, age=22}, Student{name=‘钱学森’, age=22}]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值