java put set_Java集合—Set集合去重机制

关于java里面的集合,大家经常利用到Set集合没有重复数据的特性,来进行数据的去重,那么去重的原理是怎么样的呢?最近面试了几个人,其间有聊到集合的东西,所以就顺便问了一下这个问题,但是都是只知道这么用,而没有去看看底层代码的去重原理(而恰恰有可能这些基础原理会被用来设计其他一些场景实现),所以在此文章记录一下,希望能帮助到一些人。下面是Set集合的类图:

2862d9d68d4f07770b1f9c488d789c48.png

下面我们来跟踪一下执行的过程:

1. 首先我们实例化一个set对象

Set<8大基本类型> set = new HashSet<8大基本类型>();

set.add(8大基本类型);

2.add操作会调用HashSet中的add方法,实现如下:

public boolean add(E e) {

return map.put(e, PRESENT)==null;

}

3.HashSet中的add方法依赖了HashMap的put方法,实现如下:

public V put(K key, V value) {

if (key == null)

return putForNullKey(value);

int hash = hash(key.hashCode());

int i = indexFor(hash, table.length);

for (Entry e = table[i]; e != null; e = e.next) {//每添加一个,则循环判断是否与map中的元素相等

Object k;

// 先判断hashcode是否一致,然后再判断值是否相等

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

V oldValue = e.value;

e.value = value;

e.recordAccess(this);

return oldValue;

}

}

modCount++;

addEntry(hash, key, value, i);

return null;

}

很明显上述操作对8种基本类型的数据+String型是有用的,但是如果想把去重的方式应用到复杂的对象呢,上述方式就还欠缺了一点了,知道了执行顺序和原理了的话,就知道该如何去实现了!下面就是重写对象User的实现,重写equals和hashCode方法!

测试类:

package com.test.set;

import java.util.HashSet;

import java.util.Set;

public class UniqueSet {

/**

*

* @param args

*/

public static void main(String[] args) {

User user1 = new User(1, "a");

User user2 = new User(2, "b");

User user3 = new User(3, "c");

User user4 = new User(2, "b");

Set userSet = new HashSet();

userSet.add(user1);

userSet.add(user2);

userSet.add(user3);

userSet.add(user4);

// 输入结果 id=1 username=a id=2 username=b id=3 username=c

for (User u : userSet) {

System.out.println("id=" + u.id + " " + "username=" + u.username);

}

}

}

实现类:

package com.test.set;

/**

* 类描述:set集合针对String 类型和8大基础数据类型 过滤掉重复数据,

* 如果存放的是其他类型对象,则需要重写hashCode方法和equals方法,

* 当hashcode相等时(先执行hashCode方法),则会去执行equals方法,比较每个属性的值

* 如果一致的话,则不会存进set,否则加入set集合

*

*/

public class User {

// id

protected Integer id;

// 名称

protected String username;

//构造方法

public User(Integer id, String username) {

this.id = id;

this.username = username;

}

/**

* 如果对象类型是User,先比较hashcode,一致的场合再比较每个属性的值

*/

@Override

public boolean equals(Object obj) {

if (obj == null)

return false;

if (this == obj)

return true;

if (obj instanceof User) {

User user = (User) obj;

// if(user.id = this.id) return true; // 只比较id

// 比较每个属性的值 一致时才返回true

if (user.id == this.id && user.username.equals(this.username))

return true;

}

return false;

}

/**

* 重写hashcode 方法,返回的hashCode不一样才再去比较每个属性的值

*/

@Override

public int hashCode() {

// return id.hashCode();

return id.hashCode() * username.hashCode();

}

}

标签:username,Set,Java,hashCode,add,User,集合,return,id

来源: https://blog.csdn.net/sanmi8276/article/details/113839351

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值