集合框架__【Set集合】【HashSet】【TreeSet】

---------------------------------------- android培訓java培訓、期待與您交流! ------------------------------------

 

Set:元素是無序的,不能重複
Set集合的功能和Collection是一致的,無特有方法
————HashSet:底層數據結構是哈希表
————TreeSet:底層數據結構是二叉樹

HashSet

HasnSet 通過equals方法和hashCode方法來保證元素的唯一性
———— 如果hashCode相同,還要調用equals判斷元素是否相同
———— 如果hasnCode不同,就不用判斷equals
————HashSet方法中的元素是按照哈希表來存儲的,所以打印的時候不是無序的

在hashSet中對元素contains、remove等操作時,先判斷hashCode,再判斷equals

而在 ArrayList中對元素的操作只依賴於equals方法。

所以使用HashSet時需要覆蓋equals和hashCode方法.

示例:往HashSet集合中存入自定義對象,姓名年齡相同則視爲同一個元素

HashSet示例

在Student類中覆蓋

class Student {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public int hashCode() {
		System.out.println(this.name + "...............hashCode.");
		return name.hashCode() + age * 22;// *22是爲了保證數據的唯一值
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Student)) {
			return false;
		}
		Student s = (Student) obj;
		return this.name.equals(s.name) && this.age == s.age;
	}

}

public class HashSetDemo {
	public static void main(String[] args) {
		HashSet<Object> set = new HashSet<Object>();
		set.add(new Student("java1", 20));
		set.add(new Student("java1", 20));
		set.add(new Student("java2", 20));
		set.add(new Student("java2", 20));
		set.add(new Student("java3", 20));
		set.add(new Student("java3", 20));

		Iterator<Object> it = set.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + " " + s.getAge());
		}
	}
}


 

TreeSet

TreeSet:對Set集合元素進行排序。而元素必須具有比較性才能排序

——TreeSet底層數據結構是二叉樹,位置是由compareTo的返回值決定的
——可以通過控制返回值來控制二叉樹元素位置
——保證元素唯一性的依據是:compareTo方法return 0

①TreeSet排序的第一種方式:讓元素自身具備比較性,

——元素需實現Comparable接口,覆蓋compareTo方法,這種方式稱爲元素的自然(默認)排序

Comparable接口

——強行對實現它的每個類對象進行整體排序,稱爲類的自然排序
——唯一的compareTo()方法
——返回正數0負數
排序時,當主要條件相同時,要判斷次要條件,否則元素無法存入

 

②TreeSet排序的第二種方式:元素不具備比較性,或者具備的比較性不能滿足需要
這時就讓集合具備比較性
集合在初始化時,就具備了比較方式

定義比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數

Comparator接口

具備compare()和equals兩個方法

使用方式:定義一個類,實現Comparator接口,覆蓋compare方法


 

使用示例

package collection;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

class User implements Comparable {
	private String name;
	private int age;

	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public int compareTo(Object o) {// 實現compareTo方法
		if (!(o instanceof User))// 健壯性判斷
			throw new RuntimeException("不是用戶");
		User u = (User) o;// 向下轉型
		int x = this.age - u.age;
		int y = this.name.compareTo(u.name);// String類中已經實現了Comparable接口,返回值爲int
		if (x == 0) {
			return y;
		}
		return x;
	}
}

// 實現比較器
class MyCompare implements Comparator {

	@Override
	public int compare(Object o1, Object o2) {
		User user = (User) o1;
		User user2 = (User) o2;
		int x = user.getName().compareTo(user2.getName());
		int y = user.getAge() - user2.getAge();
		if (y == 0) {
			return x;
		}
		return y;
	}

}

public class TreeSetDemo {
	public static void main(String[] args) {

		TreeSet<Object> set = new TreeSet<Object>();

		set.add(new User("123", 123));
		set.add(new User("123", 123));
		set.add(new User("123", 123));
		set.add(new User("123", 123));
		Iterator<Object> it = set.iterator();
		while (it.hasNext()) {
			User user = (User) it.next();
			System.out.println(user.getName() + " " + user.getAge());
		}
	}
}


 

【小結:Comparable和Comparator的區別

二者都是接口,需要被實現,但是Comparable是被對象實現,comparator是被比較器實現

Comparable 是一個對象本身就已經支持自比較所需要實現的接口,(如 String、Integer 等數據類對象自己就可以完成比較大小操作,已經實現了Comparable接口)可以直接使用CompareTo()方法進行比較;而一般對象需要繼承該接口,實現compareTo()方法後才能然後完成比較。如Student類需要繼承Comparable接口

Comparator可以看成一種算法的實現,將算法和數據分離; 是一個專用的比較器,當這個對象不支持自比較或者自比較函數不能滿足你的要求時,你可以寫一個比較器來完成兩個對象之間大小的比較。將比較器對象傳入TreeSet的構造函數來調用

簡單來說:一個是自已完成比較,一個是外部程序實現比較。
當兩種排序都存在時,以比較器爲主,因爲Comparator的使用更加靈活,不需要對對象進行修改

 

 

---------------------------------------- android培訓java培訓、期待與您交流! ------------------------------------


 

發佈了31 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章