现在的位置: 首页 > 综合 > 正文

Set集合的唯一性(一)——HashSet

2019年09月19日 ⁄ 综合 ⁄ 共 2025字 ⁄ 字号 评论关闭


首先set也是Collection接口的子接口,即:
  |---List
   有序(存储顺序和获取顺序一致),可重复
  |---Set 
       |---HashSet(通过HashCode和equlas保证唯一性)
       |---TreeSet(通过comparable的compareTo或者comparator的compare)
   无序(存储顺序和获取顺序不一致),不可重复

先从HashSet开始,它是不可重复的,如果存入String,或者Integer,那么java会对其默认不可重复,不需要我们再做研究,但是如果我们

要存入HashSet集合中的是自定义的类呢?
例如:

package collection;

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

public class SetDemo1 {
	public static void main(String[] args) {
		fun2();
	}

	// 对自定义类元素确保元素唯一性
	private static void fun2() {
		// 创建集合
		Set<Student> s = new HashSet<Student>();
		// 创建Student对象
		Student s1 = new Student("a", 1);
		Student s2 = new Student("b", 2);
		Student s3 = new Student("c", 3);
		Student s4 = new Student("a", 1);
		//添加元素
		s.add(s1);
		s.add(s2);
		s.add(s3);
		s.add(s4);
		// 遍历集合
		for (Student st : s) {
			System.out.println(st.getName() + "--" + st.getAge());
		}

	}

	private static void fun1() {
		// 创建set集合
		Set<String> s = new HashSet<String>();
		// 添加元素
		s.add("a");
		s.add("b");
		s.add("c");
		s.add("d");
		s.add("a");
		// 遍历
		for (String str : s) {
			System.out.print(str);
		}
	}
}

// 定义一个Student类,包含姓名年龄
class Student {
	private String name;
	private int age;

	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;
	}

}

fun1():
结果:dbca
总结:如果是String、Integer之类的元素,java会自动把重复的替换而不是重复添加到集合中
fun2():
结果: c--3
 a--1
 b--2
 a--1
总结:如果添加的是自定义类的元素,那么java则不会自动把重复的替换,即不能保证set集合的唯一性,这时就需要自己来通过

同过API,我们知道HashSet底层是由哈希表实现的,那么保证它唯一性的就是元素的HashCode和equals方法,即需要在Stduent类中重写

HashCode和equals方法。

例如:

	@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;
	}

注意补充:
 为什么重写了equals()还需要重写HashCode()?
  原因是因为在java源码中,equals()是在Hash值相同的时候才能调用到equals(),所以一定要重写HashCode(),否则Hash值都不一样也永远不可能进入到equals()中去。


【上篇】
【下篇】

抱歉!评论已关闭.