java回顾之Set

关于Set集合
它类似一个罐子,不能记住元素的添加顺序,它类似Collection,只是他不允许包含重复元素

去重复数据,我只需要把所有的数据都添加进Set,Set会自动把重复的数据去掉。如果把重复数据添加到Set中
add方法会false,同时并不会添加进去。

(什么时候用Set呢?

去重复数据,我只需要把所有的数据都添加进Set,Set会自动把重复的数据去掉。

请问你用map实现起来有这么快捷吗?

在查找数据时,我只要知道数据的key,我一次就能拿到这个数据。你用Set又行么?)

Set子类又有Hashset,TreeSet,EnumSet等

①HashSet:是Set接口的典型实现类,大多数用Set时候都用这个类,用Hash算法来存储集合元素(hash算法克制根据元素的hashcode值来快速定位元素),有较好的存储和查找性能

1.不能保证元素顺序,与添加顺序无关

2.不是同步,多线程修改集合时,需要通过代码保证同步

3.元素值可以是null

HS存储一个元素时候,会调用HashCode方法来得到该对象的HashCode值,根据此值来确定存储位置。

两个元素equals()比较为true时候,同事hashcode()方法返回值不相等,HS仍然会将两个添加成功
例如

//只重写了equals方法,但是hashcode()肯定会不等,所以会添加成功
class A
{
	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return true;
	}
}

//只重写了Hashcode方法
class B
{
	public int hashCode() {
		return 1;
	};
}


class C
{
	@Override
	public int hashCode() {
		
		return 2;
	}
	
	public boolean equals(Object obj) {
		return true;
	};
}

public class HashSetTest {
	public static void main(String[]args)
	{
		HashSet set=new HashSet<>();
		set.add(new A());
		set.add(new A());
		set.add(new B());
		set.add(new B());
		set.add(new C());
		set.add(new C());
		
		System.out.println(set);
	}
}

[vczx.A@2d11f5f1, vczx.B@1, vczx.B@1, vczx.C@2, vczx.A@5994a1e9]

HashSet中每个能存储元素的“槽位”通常称之为“桶”,例如上面例子的B类,hashcode返回相同,但是equals不同,所以,它就会在一个桶里面占两个元素,这样就会导致性能下降。

  两个A,B,一个C

因为C  equals总是返回true,hashcode总是返回2.所以add方法根据不重复原则就会只添加第一个。

所以实际应用中如果用HashSet集合时候,如果对象重写了equals方法,则也应该同时重写hashcode()方法,要不然add会两个都添加,这样就会违背使用Set的初心了

原文地址:https://www.cnblogs.com/vincentmax/p/5951011.html