1.Set集合概述

  一个不包含重复元素的集合。


2.代码引入

package com;

import java.util.HashSet;
import java.util.Set;

/**
 * Collection
 * 		List    有序(存储顺序和取出顺序一致),可重复
 * 		Set 	无序(存储顺序和取出顺序不一致),唯一
 * 		虽然Set集合的元素无序,但是,作为集合来说,它肯定有自己的存储顺序,
 * 		我们存储元素的时候可能和它内存的存储元素顺序相同。
 * 			
 * HashSet:它不保障Set的迭代器顺序,特别是它不保证顺序恒久不变。
 */
public class SetDemo {
	public static void main(String[] args) {
		//创建集合对象
		Set<String> set = new HashSet<String>();
		
		//添加元素
		set.add("hello");
		set.add("world");
		set.add("world");
		set.add("java");
		set.add("java");
		
		//遍历集合元素
		for(String str : set){
			System.out.println(str);
		}
	}
}


3.HashSet类概述

  HashSet类不保证Set的迭代顺序。

  特别是它不保证该顺序恒久不变。


HashSet如何保证元素的唯一性?

  底层数据结构是哈希表。

  哈希表依赖于哈希值存储。

package com;

import java.util.HashSet;
import java.util.Set;

/**
 * HashSet:存储字符串并遍历
 * 问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
 * 通过查看add方法,我们知道这个方法的底层依赖两个方法:hashCode()和equals()
 * 步骤:
 * 		首先比较哈希值
 * 		如果相同,继续下一步,比较地址值或者走equals()
 * 		如果不同,就直接添加到集合中
 * 
 * 如果类没有重写这两个方法,默认使用的是Object()方法。
 * 而String类重写了hashCode()和equals()方法。所以,它就可以把内容相同的字符串去掉,只留下一个。
 */
public class SetDemo {
	public static void main(String[] args) {
		//创建集合对象
		Set<String> set = new HashSet<String>();
		
		//添加元素
		set.add("hello");
		set.add("world");
		set.add("java");
		set.add("world");
		
		//遍历集合元素
		for(String str : set){
			System.out.println(str);
		}
	}
}


4.存储自定义对象

package com;

public class Student {
	private String name;
	private int age;
	
	public Student(){}
	public Student(String name,int age){
		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;
	}
	
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}			
}
package com;

import java.util.HashSet;
import java.util.Set;

/**
 *	需求:存储自定义对象,并保存元素的唯一性。
 *   要求:如果两个对象的成员变量值都相同,则为同一个元素。 
 *
 */
public class SetDemo2 {
	public static void main(String[] args) {
		//定义Set集合对象
		Set<Student> set = new HashSet<Student>();
		
		//创建学生对象
		Student s1 = new Student("哈哈",1);
		Student s2 = new Student("呵呵",2);
		Student s3 = new Student("嘻嘻",3);
		Student s4 = new Student("哈哈",1);
		Student s5 = new Student("嘻嘻",1);
		
		//添加元素
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		
		//遍历集合对象
		for(Student stu : set){
			System.out.println(stu);
		}
		
	}

}

Student [name=嘻嘻, age=3]

Student [name=呵呵, age=2]

Student [name=哈哈, age=1]

Student [name=嘻嘻, age=1]


5.LinkedhashSet类概述

  元素有序唯一。

  由链表保证元素有序。

  由哈希表保证元素唯一。

package com;

import java.util.LinkedHashSet;

public class LinkedHashSetTest {
	public static void main(String[] args) {
		//创建LinkedHashSet集合对象
		LinkedHashSet<String> set = new LinkedHashSet<String>();
		
		//添加元素
		set.add("hello");
		set.add("world");
		set.add("java");
		
		//遍历集合元素
		for(String str:set){
			System.out.println(str);
		}
	}

}


6.TreeSet类概述

  使用元素的自然顺序对元素进行排序。

  或者根据创建Set时提供的Comparator进行排序。

  具体取决于使用的构造方法。

TreeSet是通过自平衡的二叉树来保证元素的排序和唯一性。