您的位置:首页 > 编程语言 > Java开发

Java类集学习(三)Set接口

2015-12-29 19:18 519 查看
Set接口与上文所讲的List接口的区别是:

不能加入重复的元素;

接口的实例无法像List接口那样可以进行双向输出;

List接口对Collection接口进行了扩充,Set没有对Collection进行扩充,只是比Collection要求更严格了(不能加重复元素)。

set接口下面有两个常用的子类:HashSet、TreeSet和一个子接口SortedSet,下面对这几个一一介绍。

HashSet、TreeSet:Set--->无重复,Hash---->无序,Tree---->有序

本节主要介绍TreeSet的排序,去重;HashSet的去重。

1、散列存放:HashSet

hashset的实现依赖hash函数,哈希值。主要特点,里面不能存放重复的元素,采取散列的存储方式,所以没有顺序。

2、有序的存放:TreeSet

程序在向集合插入数据的时候是无序的,输出是有序的。

需要说明以下的例子并没有证明HashSet的无序性,以后在深入研究一下。现在先看一下他们的使用

public class HashSetDemo01 {
public static void main(String[] args) {
Set<String> allSet = new HashSet<String>();
allSet.add("A");
allSet.add("B");
allSet.add("D");
allSet.add("D");//重复元素不能加入
allSet.add("C");
allSet.add("E");
System.out.println(allSet);

Set<String> allSet1 = new TreeSet<String>();
allSet1.add("E");
allSet1.add("C");
allSet1.add("B");
allSet1.add("C");//重复元素不能加入
allSet1.add("A");
allSet1.add("D");
System.out.println(allSet1);
}
}
输出结果:

[A, B, C, D, E]
[A, B, C, D, E]


3、TreeSet的排序说明
怎样实现TreeSet的排序呢?TreeSet中元素是有序存放的,所以对于每一个对象必须指定好排序规则,而且TreeSet中的每个对象所在的类必须实现Comparable接口才可以正常使用。

如果你想对自己写的类排序,你就把自己写的这个类实现Comparable接口,然后重写comparaTo方法来规定这个类的对象排序的顺序。

在这个方法中,如果返回-1,则当前对象排前面;返回1,就排后面 ;0,就相等。

public class TreeSetDemo01 {
/**
* TreeSet排序
* @param args
*/
public static void main(String[] args) {
Set<Person> allSet = new TreeSet<Person>();
allSet.add(new Person("张三", 20));
allSet.add(new Person("李四", 22));
allSet.add(new Person("王五", 24));
allSet.add(new Person("王五", 24));
allSet.add(new Person("赵六", 28));
allSet.add(new Person("赵七", 28));
System.out.println(allSet);//如果不重写toString的话则输出的是地址
}
}
class Person implements Comparable<Person>{//定义一个Person类,实现比较器
private String name;
private int age;
//	通过构造方法为属性赋值
public Person(String name, int age){
this.name = name;
this.age = age;
}
//	为了输入方便,重写toString方法,如果重写toString的话则输出的是地址
public String toString(){
return "姓名:"+this.name+";年龄:"+this.age;

}
//	排序规则
@Override
public int compareTo(Person person) {
if(this.age > person.age){
return 1;//this.age排后面
}else if(this.age < person.age){
return -1;//this.age排前面
}else{
return this.name.compareTo(person.name);//增加字符串比较,年龄相等的话区分姓名
}                                               //如果姓名年龄都相等的话,为重复元素,不再排出来
}
}
输出结果:

[姓名:张三;年龄:20, 姓名:李四;年龄:22, 姓名:王五;年龄:24, 姓名:赵七;年龄:28, 姓名:赵六;年龄:28]
以上例子实现了TreeSet“去重复”、“排序”的功能,都是通过Comparable接口完成的。

然而对于HashSet此方法不能“去重”、”排序“,HashSet是无法排序的,他本身存储是无序的,排序无用,同时Comparable接口中实现的”去重“方法也不能实现了。

那么,如何针对HashSet进行去重复元素呢?

4、HashSet(后面会讲到HashMap)利用equals、HashCode去重复元素

equals--->判断对象是否相等;

HashCode--->判断对象的编码是否相等

class Person2 {
private String name;
private int age;
public Person2(String name, int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(this == obj){
return true;//地址相同是同一个对象
}
if(!(obj instanceof Person2)){
return false;//传递过来的不是本类对象,不是同一个对象
}
Person2 p = (Person2) obj;//向下转型
if(this.name.equals(p.name)&&this.age == p.age){//全部属性相等,是同一个对象
return true;
}else{
return false;
}
}
public int hashCode(){//重写HashCode
return this.name.hashCode()*this.age;
}
public String toString(){
return "姓名:"+this.name+";年龄:"+this.age;
}
}

public class TreeSetDemo01 {
/**
* HashSet去重
* @param args
*/
public static void main(String[] args) {
Set<Person2> allSet1 = new HashSet<Person2>();
allSet1.add(new Person2("张三", 20));
allSet1.add(new Person2("李四", 22));
allSet1.add(new Person2("王五", 24));
allSet1.add(new Person2("王五", 24));
allSet1.add(new Person2("赵六", 28));
allSet1.add(new Person2("赵七", 28));
System.out.println(allSet1);
}
}
输出结果:

[姓名:赵七;年龄:28, 姓名:李四;年龄:22, 姓名:张三;年龄:20, 姓名:赵六;年龄:28, 姓名:王五;年龄:24]


以上就是HashSet去重复元素的实现。

下文介绍Map接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 实例 class