Set集合.docx
《Set集合.docx》由会员分享,可在线阅读,更多相关《Set集合.docx(13页珍藏版)》请在冰豆网上搜索。
Set集合
Set集合
Set集合为集类型,集是最简单的一种集合,存放于集中的对象不按特定方式排序,只是简单地把对象加入集合中,类似于向口袋里放东西。
对集中存在的对象的访问和操作是通过对象的引用进行的,因此在集中不能存放重复对象。
Set集合包括Set接口以及Set接口的所有实现类。
因为Set接口继承了Collection接口,所以Set接口拥有Collection接口提供的所有常用方法。
(1)使用HashSet类
由HashSet类实现的Set集合的优点是能够快速定位集合中的元素。
由HashSet类实现的Set集合中的对象必须是惟一的,因此需要添加到由HashSet类实现的Set集合中的对象,需要重新实现equals()方法,从而保证插入集合中对象的标识的惟一性。
由HashSet类实现的Set集合的排列方式为按照哈希码排序,根据对象的哈希码确定对象的存储位置,因此需要添加到由HashSet类实现的Set集合中的对象,还需要重新实现hashCode()方法,从而保证插入集合中的对象能够合理地分布在集合中,以便于快速定位集合中的对象。
由于Set集合中的对象是无序的,这里所谓的无序并不是完全无序,只是不像List集合按对象的插入顺序保存对象。
例如:
源文件:
Person.java
[java]viewplaincopy
publicclassPerson{
privateStringname;
privatelongid_card;
publicPerson(Stringname,longid_card){
this.name=name;
this.id_card=id_card;
}
publiclonggetId_card(){
returnid_card;
}
publicvoidsetId_card(longid_card){
this.id_card=id_card;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicinthashCode(){//重新实现hashCode()方法
finalintPRIME=31;
intresult=1;
result=PRIME*result(int)(id_card^(id_card>>>32));
result=PRIME*result((name==null)?
0:
name.hashCode());
returnresult;
}
publicbooleanequals(Objectobj){//重新实现equals()方法
if(this==obj){
returntrue;
}
if(obj==null){
returnfalse;
}
if(getClass()!
=obj.getClass()){
returnfalse;
}
finalPersonother=(Person)obj;
if(id_card!
=other.id_card){
returnfalse;
}
if(name==null){
if(other.name!
=null){
returnfalse;
}
}
elseif(!
name.equals(other.name)){
returnfalse;
}
returntrue;
}
}
源文件:
TestSet.java
[java]viewplaincopy
importjava.util.*;
publicclassTestSet{
publicstaticvoidmain(Stringargs[]){
Set<Person>hashSet=newHashSet<Person>();
hashSet.add(newPerson("马先生",22015));
hashSet.add(newPerson("李小姐",22018));
hashSet.add(newPerson("李先生",22020));
Iterator<Person>it=hashSet.iterator();
while(it.hasNext()){
Personperson=it.next();
System.out.println(person.getName()""person.getId_card());
}
}
}
程序的运行结果如下:
李小姐22018
李先生22020
马先生22015
如果既想保留HashSet类快速定位集合中对象的优点,又想让集合中的对象按插入的顺序保存,可以通过HashSet类的子类LinkedHashSet实现Set集合,即修改上述代码如下:
将Set<Person>hashSet=newHashSet<Person>();修改为:
Set<Person>hashSet=newLinkedHashSet<Person>();
(2)使用TreeSet类
TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证在遍历集合时按照递增的顺序获得对象。
遍历对象时可能是按照自然顺序递增排列,因此存入用TreeSet类实现的Set集合的对象必须实现Comparable接口;也可能是按照指定比较器递增排序,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。
TreeSet类通过实现java.util.SortedSet接口增加的方法如下表4所示:
例如:
源文件:
Person.java
[java]viewplaincopy
publicclassPersonimplementsComparable{
privateStringname;
privatelongid_card;
publicPerson(Stringname,longid_card){
this.name=name;
this.id_card=id_card;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publiclonggetId_card(){
returnid_card;
}
publicvoidsetId_card(longid_card){
this.id_card=id_card;
}
publicintcompareTo(Objecto){//默认按编号升序排序
Personperson=(Person)o;
intresult=id_card>person.id_card?
1:
(id_card==person.id_card?
0:
-1);
returnresult;
}
}
源文件:
TestSet.java
[java]viewplaincopy
importjava.util.*;
publicclassTestSet{
publicstaticvoidmain(Stringargs[]){
TreeSet<Person>treeSet=newTreeSet<Person>();
Personp1=newPerson("马先生",22015);
Personp2=newPerson("李先生",22016);
Personp3=newPerson("王小姐",22018);
Personp4=newPerson("尹先生",22020);
Personp5=newPerson("王先生",22012);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
treeSet.add(p4);
treeSet.add(p5);
System.out.println("初始化的集合:
");
Iterator<Person>it=treeSet.iterator();
while(it.hasNext()){
Personp=it.next();
System.out.println(p.getId_card()""p.getName());
}
System.out.println("截取前面部分得到的集合:
");
it=treeSet.headSet(p1).iterator();
while(it.hasNext()){
Personp=it.next();
System.out.println(p.getId_card()""p.getName());
}
System.out.println("截取中间部分得到的集合:
");
it=treeSet.subSet(p1,p3).iterator();
while(it.hasNext()){
Personp=it.next();
System.out.println(p.getId_card()""p.getName());
}
System.out.println("截取后面部分得到的集合:
");
it=treeSet.tailSet(p3).iterator();
while(it.hasNext()){
Personp=it.next();
System.out.println(p.getId_card()""p.getName());
}
}
}
程序的运行结果如下:
初始化的集合:
22012王先生
22015马先生
22016李先生
22018王小姐
22020尹先生
截取前面部分得到的集合:
22012王先生
截取中间部分得到的集合:
22015马先生
22016李先生
截取后面部分得到的集合:
22018王小姐
22020尹先生
在使用由TreeSet类实现的Set集合时,也可以通过单独的比较器对集合中的对象进行排序。
例如:
比较器既可以作为一个单独的类,也可以作为对应类的内部类,本例中移内部类的形式实现比较器。
源文件:
Person.java
[java]viewplaincopy
importjava.util.Comparator;
publicclassPersonimplementsComparable{
privateStringname;
privatelongid_card;
publicPerson(Stringname,longid_card){
this.name=name;
this.id_card=id_card;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publiclonggetId_card(){
returnid_card;
}
publicvoidsetId_card(longid_card){
this.id_card=id_card;
}
publicintcompareTo(Objecto){//默认按编号升序排序
Personperson=(Person)o;
intresult=id_card>person.id_card?
1:
(id_card==person.id_card?
0:
-1);
returnresult;
}
staticclassPersonComparatorimplementsComparator{
publicstaticfinalintNAME=1;
publicstaticfinalintID_CARD=2;
privateintorderByColumn=1;//默认为按姓名排序
publicstaticfinalbooleanASC=true;
publicstaticfinalbooleanDESC=false;
privatebooleanorderByMode=true;//默认为按升序排序
publicintcompare(Objecto1,Objecto2){//实现Comparator接口的方法
Personp1=(Person)o1;
Personp2=(Person)o2;
intresult=0;//默认的判断结果为两个对象相等
switch(orderByColumn){//判断排序条件
case1:
Strings1=CnToSpell.getFullSpell(p1.getName());
Strings2=CnToSpell.getFullSpell(p2.getName());
if(orderByMode){//升序
result=pareTo(s2);
}
else{//降序
result=pareTo(s1);
}
break;
case2:
if(orderByMode){//升序
result=(int)(p1.getId_card()-p2.getId_card());
}
else{//降序
result=(int)(p2.getId_card()-p1.getId_card());
}
break;
}
returnresult;
}
publicvoidorderByColumn(intorderByColumn){//用来设置排序条件
this.orderByColumn=orderByColumn;
}
publicvoidorderByMode(booleanorderByMode){//用来设置排序方式
this.orderByMode=orderByMode;
}
}
}
源文件:
TestSet.java
[java]viewplaincopy
importjava.util.*;
publicclassTestSet{
publicstaticvoidmain(Stringargs[]){
TreeSet<Person>treeSet1=newTreeSet<Person>();
Personp1=newPerson("马先生",22015);
Personp2=newPerson("李先生",22016);
Personp3=newPerson("王小姐",22018);
treeSet1.add(p1);
treeSet1.add(p2);
treeSet1.add(p3);
System.out.println("客户化排序前,默认按编号升序排序:
");
//新创建一个Set集合,不进行客户化排序,默认按编号升序排序
TreeSet<Person>treeSet2=newTreeSet<Person>(treeSet1);//通过构造函数初始化集合
Iterator<Person>it1=treeSet2.iterator();
while(it1.hasNext()){
Personp=it1.next();
System.out.println(p.getId_card()""p.getName());
}
System.out.println("客户化排序后,按编号降序排序:
");
//新创建一个Set集合,进行客户化排序,客户化排序方式为按编号降序排序
Person.PersonComparatorpc=newPerson.PersonComparator();//创建比较器(内部类)的实例
pc.orderByColumn(Person.PersonComparator.ID_CARD);//设置排序依据的属性
pc.orderByMode(Person.PersonComparator.DESC);//设置排序方式
TreeSet<Person>treeSet3=newTreeSet<Person>(pc);//必须通过构造函数设置比较器
treeSet3.addAll(treeSet1);//初始化集合
Iterator<Person>it2=treeSet3.iterator();
while(it2.hasNext()){
Personp=it2.next();
System.out.println(p.getId_card()""p.getName());
}
}
}
程序的运行结果如下:
客户化排序前,默认按编号升序排序:
22015马先生
22016李先生
22018王小姐
客户化排序后,按编号降序排序:
22018王小姐
22016李先生
22015马先生