Set 是Collection接口的另一个较常用的子接口,根据底层数据结构的不同,Set接口又实现了很多的子类,其中在开发最常用的有两种,分别是:HashSet和TreeSet。
Set集合中的元素是无序的,即元素存入和取出的顺序不一定一致,而且元素不可以重复,但其功能和Collection是一致的
import java.util.*;
class Student{
private String name;
public Student(String name){
this.name=name;
}
//获取哈希值
public int hashCode(){
return name.hashCode();
}
//复写equals方法通过返回来的哈希值来判断两个元素是否为相同
public boolean equals(Object obj){
Student s=(Student)obj;
if(!(obj instanceof Student)){
return false;
}
return this.name.equals(s.name);//判断“张三”和“李四”是否是同一元素
}
public String getName(){
return this.name;
}
}
public class HashSetDemo {
public static void main(String[] args){
HashSet hs=new HashSet();
Student stu1=new Student("张三");
Student stu2=new Student("李四");
hs.add(stu1);
hs.add(stu2);
Iterator it=hs.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s.getName());
}
}
}
class TreeSetDemo{
public static void main(String[] args){
TreeSet<Integer> ts=new TreeSet<Integer>();
ts.add(8);
ts.add(9);
ts.add(5);
ts.add(3);
Iterator<Integr> it=ts.iterator();
while(it.hasNext()){
System.out.print(it.next()+"\t");
}
}
}
TreeSet支持两种排序方式:自然排序和自定义选择器排序,默认情况下是自然排序。
在JDK中,有一部分类实现了Comparable接口,如Integer,Double和String等,Comparable接口有一个compareTo(Object o)方法,它返回整数类型,对于表达式x.compareTo(y),如果返回值为0,表示x和y相等,如果返回值大于0,表示x大于y,如果小于0,表示x<y,TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排序,这种方式称为自然排序。
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性,即自定义选择器,并在集合初始化时,就有了比较方式
当两种排序都存在时,以比较器为主,定义一个类,实现Comparator接口,覆盖compare方法。
如:
//定义字符串长度比较器实现Comparator方法
class StrLenComparator implements Comparator<String>{
public int compare(String o1,String o2){
String str1=(String)o1;
String str2=(String)o2;
int num= new Integer(str1.length()).compareTo(new Integer(str2.length()));//比较str1和str2的长度,返回一个int类型的数值
if(num==0){
num=str1.compareTo(str2);//若两个字符串长度相等,则比较它们在字典中的顺序
}
return num;
}
}
public class TreeSetTest {
public static void main(String[] args){
StrLenComparator comparator=new StrLenComparator();
TreeSet<String> ts=new TreeSet<String>(comparator);
ts.add("adgienfn");
ts.add("afefgv");
ts.add("a");
ts.add("aa");
ts.add("af");
ts.add("afegv");
ts.add("ff");
Iterator<String> it=ts.iterator();
while(it.hasNext()){
String str=it.next();
sop(str);
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
其打印结果为:
a
aa
af
ff
afegv
afefgv
adgienfn
1,HashSet
HashSet的底层数据结构是哈希表,即按照哈希算法来存取集合中的元素,存取速度比较快,属于非线程同步,因而安全性较低。
HashSet是通过元素的两方法,HashCode和equals来保证元素唯一性的的。
如果元素的HashCode值相同,才会判断equals是否为true。
如下面的例子,首先new一个“张三”添加到集合中去,底层数据会自动调用对象的hashCode()方法获得哈希值,然后根据这个哈希值,进一步计算出对象在集合中的存放位置。在new“李四”时,底层数据同样调用对象的hashCode()方法获得哈希码值,并计算对象在集合中的存放位置。如果“张三”和“李四”的哈希值相同,底层数据会调用equals()方法来做判断,若返回ture,表示它们是同一个元素,则“李四”不能添加进集合,若返回false表示不是同一个元素,可以添加进集合。
注意事项: 对于判断元素是否存在,以及删除等操作,依赖的方式都是元素的HashCode和equals方法。import java.util.*;
class Student{
private String name;
public Student(String name){
this.name=name;
}
//获取哈希值
public int hashCode(){
return name.hashCode();
}
//复写equals方法通过返回来的哈希值来判断两个元素是否为相同
public boolean equals(Object obj){
Student s=(Student)obj;
if(!(obj instanceof Student)){
return false;
}
return this.name.equals(s.name);//判断“张三”和“李四”是否是同一元素
}
public String getName(){
return this.name;
}
}
public class HashSetDemo {
public static void main(String[] args){
HashSet hs=new HashSet();
Student stu1=new Student("张三");
Student stu2=new Student("李四");
hs.add(stu1);
hs.add(stu2);
Iterator it=hs.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s.getName());
}
}
}
2,TreeSet
TreeSet的底层数据结构是二叉树,它实现了SortedSet接口,能够对集合中的对象进行排序.
如:
import java.util.*;class TreeSetDemo{
public static void main(String[] args){
TreeSet<Integer> ts=new TreeSet<Integer>();
ts.add(8);
ts.add(9);
ts.add(5);
ts.add(3);
Iterator<Integr> it=ts.iterator();
while(it.hasNext()){
System.out.print(it.next()+"\t");
}
}
}
输出结果为:3 5 8 9
当TreeSet向集合中加入一个对象时,会把它插入到有序的对象序列中,那么TreeSet是如何对对象进行排序的呢?TreeSet支持两种排序方式:自然排序和自定义选择器排序,默认情况下是自然排序。
在JDK中,有一部分类实现了Comparable接口,如Integer,Double和String等,Comparable接口有一个compareTo(Object o)方法,它返回整数类型,对于表达式x.compareTo(y),如果返回值为0,表示x和y相等,如果返回值大于0,表示x大于y,如果小于0,表示x<y,TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排序,这种方式称为自然排序。
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性,即自定义选择器,并在集合初始化时,就有了比较方式
当两种排序都存在时,以比较器为主,定义一个类,实现Comparator接口,覆盖compare方法。
如:
//定义字符串长度比较器实现Comparator方法
class StrLenComparator implements Comparator<String>{
public int compare(String o1,String o2){
String str1=(String)o1;
String str2=(String)o2;
int num= new Integer(str1.length()).compareTo(new Integer(str2.length()));//比较str1和str2的长度,返回一个int类型的数值
if(num==0){
num=str1.compareTo(str2);//若两个字符串长度相等,则比较它们在字典中的顺序
}
return num;
}
}
public class TreeSetTest {
public static void main(String[] args){
StrLenComparator comparator=new StrLenComparator();
TreeSet<String> ts=new TreeSet<String>(comparator);
ts.add("adgienfn");
ts.add("afefgv");
ts.add("a");
ts.add("aa");
ts.add("af");
ts.add("afegv");
ts.add("ff");
Iterator<String> it=ts.iterator();
while(it.hasNext()){
String str=it.next();
sop(str);
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
其打印结果为:
a
aa
af
ff
afegv
afefgv
adgienfn