Java类集学习(三)Set接口

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接口。

发布了36 篇原创文章 · 获赞 4 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章