Java新人之路 -- Set集合如何实现不重复

Set集合中如何实现不重复?

Set集合是Collection的子类集合,属于单列集合

其特点及使不允许重复和不保证输出顺序,在此探讨一下其实现不重复的方法

以以下代码为例

public static void main(String[] args) {
		method2();
	}

public static void method2() {
		Set set = new HashSet();
		set.add(new User(1,"东北平原"));//每次创建对象,都会运行一个hashcode
		set.add(new User(2,"华北平原"));
		set.add(new User(3,"长江中下游平原"));
		set.add(new User(4,"关中平原"));
		set.add(new User(2,"华北平原"));
		System.out.println(set);	
	}
	
public class User {

//地区编号
private int id;
//地区名字
private String name;

private User() {
}

public User(int id, String name) {
	super();
	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 + "]";
}

@Override
public int hashCode() {
	System.out.println("-hashcode 默认的-");
	return super.hashCode();
}

@Override
public boolean equals(Object obj) {
	System.out.println("-equals 默认的-");
	return super.equals(obj);
}

以上代码的输出结果是

-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
[User [id=2, name=华北平原], User [id=2, name=华北平原], User [id=3, name=长江中下游平原], User [id=4, name=关中平原], User [id=1, name=东北平原]]

我们可以从中发现每次创建一个对象之后,系统会先运行hashCode()进行地址的比较

所以我们进行修改

@Override
	public int hashCode() {
		System.out.println("-hashcode 默认的-");
		return 1;//设定一个固定值从而让所有的对象的地址相同
		}

再次运行主程序

-hashcode 默认的-
-hashcode 默认的-
-equals 默认的-
-hashcode 默认的-
-equals 默认的-
-equals 默认的-
-hashcode 默认的-
-equals 默认的-
-equals 默认的-
-equals 默认的-
-hashcode 默认的-
-equals 默认的-
-equals 默认的-
-equals 默认的-
-equals 默认的-
[User [id=1, name=东北平原], User [id=2, name=华北平原], User [id=3, name=长江中下游平原], User [id=4, name=关中平原], User [id=2, name=华北平原]]

我们可以发现,如果在所有的对象的地址相同的情况下,程序就会运行 equals(Object obj)对值进行对比。先进来两个对象,然后运行equals对两个对象进行对比,然后再进来一个对象,将这个对象和之前的两个对象再进行对比…

最后我们做出以下修改

@Override
public int hashCode() {
	System.out.println("-hashcode 默认的-");
	//return 1;//如果使用固定值,所有的对象地址相同,会造成哈希冲突
	//降低哈希冲突
	return this.id + this.name.hashCode();//只要地区代号和名字的哈希值不同就会识别为不同的地址
}

@Override
public boolean equals(Object obj) {
	System.out.println("-equals 默认的-");
	User user = (User)obj;
	int temp = this.id - user.id;
	if(temp == 0) {//地区编号相同的时候才去比较名字
		return this.name.equals(user.name);
	}
	return false;
}

这种情况下,程序就会先运行hashCode()对数据的地址进行判断,只要地区代号和名字的哈希值不同就会识别为不同的地址。而如果地址相同,则会运行 equals(Object obj),对地区编号和名字进行对比。正是使用这种方法,set集合保证了元素的不重复

结果如下
-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
-hashcode 默认的-
-equals 默认的-
[User [id=3, name=长江中下游平原], User [id=2, name=华北平原], User [id=1, name=东北平原], User [id=4, name=关中平原]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值