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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章