Set集合去重的原理 | 您所在的位置:网站首页 › 前端set去重 › Set集合去重的原理 |
hash值:是一个十进制的整数,由系统随机给出,它是数据的逻辑地址值,而不是实际存储的物理地址 == :比较的是数据实际存储的物理地址 Set 集合去除重复数据的原理: public static void main(String[] args) { Set set = new HashSet(); String str1 = "1"; String str2 = "2"; String str3 = "1"; set.add(str1); set.add(str2); set.add(str3); for (String string : set ) { System.out.println(string); } } 控制台打印: 1 2我们以 set.add(str3); 为例,add方法会调用 str3 的 hashCode 方法,计算它的hash值,然后在Set集合中寻找是否存在与 str3 相同hash值的元素,如果存在,那么就会导致hash冲突,但是hash值相同也不能判定两个元素的值就一定是相同的(如字符串“重地”和“通话”的hash值都是1179395),str3 会调用 equals 方法与 hash 值相同的元素进行比较 ,如果返回true,则说明两个元素是相同的,就不会将 str3 存储到Set集合中;如果返回false,则说明两个元素是不同的,就会将 str3 存储到Set集合中。 总结: Set集合去重主要是调用 add 方法时,使用了 hashCode 方法和 equals 方法:如果在 Set集合 中找不到与该元素 hashCode 值相同的元素,则说明该元素是新元素,会被添加到 Set 集合中;如果两个元素的 hashCode 值相同,并且使用 equals 方法比较后,返回值为 true,那么就说明两个元素相同,新元素不会被添加到 Set 集合中;如果 hashCode 值相同,但是 equals 方法比较后,返回值为 false ,则两个元素不相同,新元素会被添加到 Set 集合中。 方法返回值说明hashCode() == true && equals () == truetrue判定元素重复hashCode() == true && equals() == falsefalse判定元素不重复hashCode() == falsefalse判定元素不重复利用 Set 集合存储自定义类型元素,并将重复的数据去除 什么是自定义类型元素?比如我新建了一个 User 类,那么这个 User 类就是一个自定义类型元素。 场景1:使用 Set集合存储User ,并且不能有重复数据 通常可能我们都是这么做 public class User { private int id; private String name; public User(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } public static void main(String[] args) { Set hs = new HashSet(); //初始化 u1 User u1 = new User(1,"zs"); //初始化 u2 User u2 = new User(1,"zs"); //将 u1和 u2都加入到 HashSet集合中 hs.add(u1); hs.add(u2); //遍历输出HashSet集合 for (User h : hs) { System.out.println(h); } } } 控制台打印: User{id=1, name='zs'} User{id=1, name='zs'}为什么会这样呢?通过Set集合去重的原理我们发现去除重复的数据需要调用自定义元素的 HashCode 方法和 equals 方法,所以我们需要在 User 类中重写 HashCode 方法和 equals 方法。 重写后: public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public User(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } //重写 equals 方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return id == user.id && Objects.equals(name, user.name); } //重写 hashCode 方法 @Override public int hashCode() { return Objects.hash(id, name); } public static void main(String[] args) { HashSet hs = new HashSet(); User u1 = new User(1,"zs"); User u2 = new User(1,"zs"); hs.add(u1); hs.add(u2); for (User h : hs) { System.out.println(h); } } } 控制台打印: User{id=1, name='zs'}总结:Set 存储自定义类型元素,并要去除重复的元素时,需要在该元素中重写 HashCode 方法和 equals 方法。 |
CopyRight 2018-2019 实验室设备网 版权所有 |