KS-JAVA-Day5

1.集合

在这里插入图片描述

集合体系结构

起源:Collection

在这里插入图片描述
在其可使用的方法中就可看出,该集合无索引

List–在Collection的基础上增加了索引

在这里插入图片描述
其中ArrayList为List的数组实现类,LinkedList为List的链表实现类
在这里插入图片描述

Set–在Collection的基础上增加了不可重复的约束

其都是通过哈希表的方法来判断是否重复,其中LinkedHashSet继承了HashSet实现了存取有序,TreeSet则可将Comparable传入构造器使得其中元素按Comparable的规则排序。

HashCode&Equanls

先看一个约定:被equals判为相同的两个对象产生的哈希值必须相同。

哈希值

哈希值是啥?它不能做为对象的唯一标识,即不能当对象的身份证用,所以多个对象可能用着同一个哈希值。那还要这玩意有啥用?
有用!主要是给哈希表用的。哈希表在存储对象时会根据对象的哈希值来计算对象要存储的下标。

哈希表

了解一下哈希表:
在这里插入图片描述
先通过哈希值计算得下标,若下标处无对象则存储,有对象则比较:
在这里插入图片描述
可以看到,有了哈希值之后可以很方便的通过其计算下标来提高效率,否则只能将要存的对象整表遍历的去比较equals。
约定的作用:
所以我们可以先用哈希值去判断对象是否相同,若哈希值判断不了则再用equals判断,可以提高判断的效率。

为什么重写equals必须重写hashcode

就是为了满足约定:被equals判为相同的两个对象产生的哈希值必须相同。
不重写:

public class TestEquHash {   // 测试类,重写了equals 没重写 hashCode
    private String s;
    public TestEquHash(String s) {this.s = s;}
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TestEquHash that = (TestEquHash) o;
        return Objects.equals(s, that.s);
    }
}

结果:

class Te {
    public static void main(String[] args) {
        TestEquHash te1 = new TestEquHash("abc");
        TestEquHash te2 = new TestEquHash("abc");
        System.out.println(te1.equals(te2));  // 重写了equals 比值 返回 true
        Map map = new HashMap();
        map.put(te1, 111);   // 由于没有重写 hashCode 方法 ,te1和te2 的 hashCode不同
        map.put(te2, 222);   // 两者存储在哈希表的不同下标位置,但他们的键值是相等的 都是 “abc” 与键值唯一冲突
        System.out.println(map.get(te1));   // 输出 111
        System.out.println(map.get(te2));   // 输出 222
    }
}

重写:

public class TestEquHash {   // 测试类,重写了equals 和 hashCode
    private String s;
    public TestEquHash(String s) {this.s = s;}
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TestEquHash that = (TestEquHash) o;
        return Objects.equals(s, that.s);
    }
    @Override
    public int hashCode() {
        return Objects.hash(s);
    }
}

结果:

class Te {
    public static void main(String[] args) {
        TestEquHash te1 = new TestEquHash("abc");
        TestEquHash te2 = new TestEquHash("abc");
        System.out.println(te1.equals(te2));  // 重写了equals 比值 返回 true
        Map map = new HashMap();
        map.put(te1, 111);   // 由于重写了 hashCode 方法 ,te1 te2 的 hashCode相同
        map.put(te2, 222);   // 两者会存储在哈希表同一下标位置,再加上它们的键值是相等的,都是 “abc”,所以value会被覆盖,保证了键值的唯一性
        System.out.println(map.get(te1));   // 输出 222
        System.out.println(map.get(te2));   // 输出 222
    }
}

具体实现

问题:
假如对象Obj有三个字段:A,B,C。现在要求A,B字段相同的对象就是同一个对象。
解决:

  1. 重写equals方法,当两个对象的A,B都相同时返回true,否则返回false
  2. 重写hashcode方法(想办法满足约束),将A,B两个字段送入Object.hash()方法中生成哈希值并返回,使得当对象A,B字段相同时哈希值就一定相同,即equals判断为true时哈希值相同
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值