------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Set
一、概述
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。
Set集合的功能和Collection是一致的。
二、HasSet
HashSet:线程不安全,存取速度快。
可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。去除重复元素
思路:1、对人描述,将人的一些属性等封装进对象
2、定义一个HashSet容器,存储人对象
3、取出
*/
import java.util.*;
//人描述
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
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;
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode()
{
return this.name.hashCode()+this.age;
}
}
class HashSetTest
{
public static void main(String[] args)
{
HashSet h=new HashSet();
h.add(new Person("shenm",10));
h.add(new Person("shenm2",6));
h.add(new Person("shenm1",30));
h.add(new Person("shenm0",10));
h.add(new Person("shenm0",10));
getOut(h);
}
//取出元素
public static void getOut(HashSet h)
{
for (Iterator it=h.iterator(); it.hasNext(); )
{
Person p=(Person)it.next();
sop(p.getName()+"..."+p.getAge());
}
}
//打印
public static void sop(Object obj)
{
System.out.println(obj);
}
}
三、TreeSet
1、特点
a、底层的数据结构为二叉树结构(红黑树结构)
b)可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。
java中的很多类都具备比较性,其实就是实现了Comparable接口。
注意:排序时,当主要条件相同时,按次要条件排序。
c、保证数据的唯一性的依据:通过compareTo方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同。相等时则不会存入。
2、Tree排序的两种方式
1)第一种排序方式:自然排序
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。
示例:
import java.util.*;
//学生类
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age));
}
}
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet t=new TreeSet();
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));
for (Iterator it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}
}
2
)第二种方式:比较器
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。
当两种排序都存在时,以比较器为主。
示例:
/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。
*/
import java.util.*;
//学生类
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age));
}
}
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet t=new TreeSet(new LenCompare());
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));
for (Iterator it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}
}
//定义一个比较器,以姓名长度为主要比较
class LenCompare implements Comparator
{
public int compare(Student s1,Student s2)
{
int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));
if (num==0)
{
return new Integer(s1.getAge()).compareTo(s2.getAge());
}
return num;
}
}