Set:里面的元素是无序的,且集合里面的元素不可以重复
它里面有hashSet和treeSet两个常用的子集。
hashSet:底层的数据结构是哈希表。所以它实现元素唯一性的方法就是通过hashcode和equals。当往集合里面储存元素的时候,每新建一个对象,函数内部都会调用hashcode方法生成一个特有的哈希值,当后面的值再进入集合时,再新建对象时,就会与之前的哈希值相比较,如果哈希值相同,就直接不存入集合中,如果哈希值相同,就会再调用equals方法,而且,对于判断元素是否存在于集合中,也是依赖的hashcode和equals方法。
</pre><pre name="code" class="java">class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String []args)
{
HashSet hs=new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
Iterator it=hs.iterator();
while(it.hashNext())
{
Person p=(Person)it.next();
sop(p.getName()+"..."+p.getAge());
}
}
}
class Person
{
private int age;
private String name;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public int hashCode()
{
//System.out.println(this.name+"...hashCode");
return name.hashCode()+age*39;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person ))
return false;
Person p=(Person)obj;
System.out.println(this.name+",equals,,"+p.name);
return this.name.equals(p.name)&&this.age==p.age;
}
}
在以上代码中,我们需要往集合中存入自定义的对象,且不能存入重复的元素。
这里我们只需要注意的就是复写的hashCode函数和equals函数,因为objcet类中有这两个函数存在。
因为每次通过新建对象再往里面存入对象的的时候,哈希值肯定是不同的,即使再调用equals方法,父类中的equals方法也是通过比较对象的地址值,所以应用之前的方法是不行的,所以需要我们复写那两个方法,写入我们自己的比较方式。首先复写hashcode时,千万不要写成hascode了,其次,就是我们要用自己的方式来生成哈希值。
再复写equals方法的时候也是,父类的是按照地址值来比较,而上例中,我们是希望同过姓名和年龄来比较。首先要注意的是方法中需要传入的对象一定要是一个object的对象,因为传入的对象的类型我们是不清楚的。而在函数的内部我们只需要判断一下对象的类型就可以了,这里用到了之前提到过的一个关键字:instanceof,最后,再写入我们需要的比较方法就可以了。
而在主函数中,只需要把对象传入容器中,用迭代器取出容器中的元素就可以了,但是这里也有值得注意的地方。比如我们在打印的时候不能直接用iterator的对象来调用Person类中的get方法,必须先做一个转型,才可以使用。。。
treeSet里面的东西比较复杂,就不和hashSet的一起讲了。