Java集合:Set接口總結

Set 集合不容許包含相同的元素,若是試把兩個相同的元素加入同一個 Set 集合中,則添加操做失敗。html

Set 判斷兩個對象是否相同不是使用 == 運算符,而是根據 equals 方法。java

Set實現類:HashSet、LinkedHashSet、TreeSetshell

HashSet:經過散列表存信息,無序存儲,元素必須定義hashCode();數據結構

LinkedHashSet:內部使用鏈表維護元素順序,按順序插入順序排序,也必須定義hashCode();函數

TreeSet:經過樹結構(和TreeMap一致,使用紅黑樹)存儲元素,存儲數據有序。性能

HashSet :this

一、當向 HashSet 集合中存入一個元素時,HashSet 會調用該對象的 hashCode() 方法來獲得該對象的hashCode 值, 而後根據 hashCode 值決定該對象在 HashSet 中的存儲位置。spa

二、若是兩個元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會把它們存儲在不一樣的位置,但依然能夠添加成功。code

三、HashSet 集合判斷兩個元素相等的標準:兩個對象經過 equals() 方法比較相等,而且兩個對象的hashCode() 方法返回值也相等。即:若是兩個對象經過 equals() 方法返回 true,這兩個對象的hashCode 值也應該相同。htm

重寫 hashCode() 方法的基本原則:

一、在程序運行時,同一個對象屢次調用 hashCode() 方法應該返回相同的值。

二、當兩個對象的 equals() 方法比較返回 true 時,這兩個對象的 hashCode() 方法的返回值也應相等。

三、對象中用做 equals() 方法比較的 Field,都應該用來計算 hashCode 值。

 

LinkedHashSet :

一、LinkedHashSet 是 HashSet 的子類。

二、LinkedHashSet 集合根據元素的 hashCode 值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,這使得元素看起來是以插入順序保存的。

三、LinkedHashSet 性能插入性能略低於 HashSet,但在迭代訪問 Set 裏的所有元素時有很好的性能。

四、LinkedHashSet 有序但不容許集合元素重複。

 

TreeSet:

TreeSet 是 SortedSet 接口的實現類,TreeSet 能夠確保集合元素處於排序狀態。

TreeSet 支持兩種排序方法:天然排序和定製排序。默認狀況下,TreeSet 採用天然排序。

排序:

一、TreeSet 會調用集合元素的 compareTo(Object obj) 方法來比較元素之間的大小關係,

     而後將集合元素按升序排列。

二、若是試圖把一個對象添加到 TreeSet 時,則該對象的類必須實現 Comparable 接口。

三、實現 Comparable 的類必須實現 compareTo(Object obj) 方法,兩個對象即經過

    compareTo(Object obj)方法的返回值來比較大小。

注意:

向 TreeSet 中添加的應該是同一個類的對象,

當須要把一個對象放入 TreeSet 中,重寫該對象對應的 equals() 方法時,應保證該方法與

compareTo(Object obj) 方法有一致的結果:即若是兩個對象經過 equals() 方法比較返回 true,

則經過 compareTo(Object obj) 方法比較應返回 0。

天然排序:

import java.util.*;

/*
 TreeSet:能夠對Set集合中的元素進行排序。
	 底層數據結構是二叉樹。
	 保證元素惟一性的依據:
	 compareTo方法return 0.

	 TreeSet排序的第一種方式:讓元素自身具有比較性。
	 元素須要實現Comparable接口,覆蓋compareTo方法。
	 也種方式也成爲元素的天然順序,或者叫作默認順序。

	 TreeSet的第二種排序方式。
	 當元素自身不具有比較性時,或者具有的比較性不是所須要的。
	 這時就須要讓集合自身具有比較性。
	 在集合初始化時,就有了比較方式。

 需求:
 往TreeSet集合中存儲自定義對象學生。
 想按照學生的年齡進行排序。

 記住,排序時,當主要條件相同時,必定判斷一下次要條件。
 */

class Treeset {
	public static void main(String[] args) {
		Set ts = new TreeSet();

		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lisi007", 20));
		ts.add(new Student("lisi09", 19));
		ts.add(new Student("lisi08", 19));
		// ts.add(new Student("lisi007",20));
		// ts.add(new Student("lisi01",40));

		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu = (Student) it.next();
			System.out.println(stu.getName() + "..." + stu.getAge());
		}
	}
}

class Student implements Comparable// 該接口強制讓學生具有比較性。
{
	private String name;
	private int age;

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

	public int compareTo(Object obj) {
		// return 0;
		if (!(obj instanceof Student))
			throw new RuntimeException("不是學生對象");
		Student s = (Student) obj;

		System.out.println(this.name + "....compareto....." + s.name);
		if (this.age > s.age)
			return 1;
		if (this.age == s.age) {
			return this.name.compareTo(s.name);
		}
		return -1;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
}

定製排序:

import java.util.*;

/*
當元素自身不具有比較性,或者具有的比較性不是所須要的。
這時須要讓容器自身具有比較性。
定義了比較器,將比較器對象做爲參數傳遞給TreeSet集合的構造函數。

當兩種排序都存在時,以比較器爲主。

定義一個類,實現Comparator接口,覆蓋compare方法。
*/
class Student implements Comparable//該接口強制讓學生具有比較性。
{
    private String name;
    private int age;

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

    public int compareTo(Object obj)
    {
        //return 0;
        if(!(obj instanceof Student))
            throw new RuntimeException("不是學生對象");
        Student s = (Student)obj;

        //System.out.println(this.name+"....compareto....."+s.name);
        if(this.age>s.age)
            return 1;
        if(this.age==s.age)
        {
            return this.name.compareTo(s.name);
        }
        return -1;
    }

    public String getName()
    {
        return name;

    }
    public int getAge()
    {
        return age;
    }
}

class TreeSetDemo2 
{
    public static void main(String[] args) 
    {
        Set ts = new TreeSet();

        ts.add(new Student("lisi02",22));
        ts.add(new Student("lisi02",21));
        ts.add(new Student("lisi007",20));
        ts.add(new Student("lisi09",19));
        ts.add(new Student("lisi06",18));
        ts.add(new Student("lisi06",18));
        ts.add(new Student("lisi007",29));
        //ts.add(new Student("lisi007",20));
        //ts.add(new Student("lisi01",40));

        Iterator it = ts.iterator();
        while(it.hasNext())
        {
            Student stu = (Student)it.next();
            System.out.println(stu.getName()+"..."+stu.getAge());
        }
    }
}

class MyCompare implements Comparator
{
    public int compare(Object o1,Object o2)
    {
        Student s1 = (Student)o1;
        Student s2 = (Student)o2;

        int num = s1.getName().compareTo(s2.getName());
        if(num==0)
        {
            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
            /*
            if(s1.getAge()>s2.getAge())
                return 1;
            if(s1.getAge()==s2.getAge())
                return 0;
            return -1;
            */
        }
        return num;
    }
}

性能分析:能夠參考《Thinking in java》,數據以下:

------------- TreeSet -------------
 size       add  contains   iterate
   10      1316       506       180
  100       199       101        22
 1000       250       174        19
10000       266       224        21
------------- HashSet -------------
 size       add  contains   iterate
   10      1717       325       242
  100        59        16        43
 1000        66        25        27
10000        66        28        25
---------- LinkedHashSet ----------
 size       add  contains   iterate
   10       516       151        72
  100       127        40        29
 1000       145        57        27
10000       125        53        25

能夠看出HashSet性能基本總比TreeSet好 ,除非肯定須要排序時,才該使用TreeSet。

 

該博客僅做爲複習記錄。

本文大多數參考:http://www.cnblogs.com/shellway/p/3709074.html

相關文章
相關標籤/搜索