- 不包含重复元素的集合
- set集合是无序
- set集合中也可以存储null 但是只能存储一个
在set中判断元素是否重复 使用equals() 方法 如果两个对象的equals方法返回true 则他们的hashcode值应该也是相等的。
换句话来说:如果两个对象的equals返回是true 但是hashcode不一致 则也会认为元素不重复
Set实现类之一:HashSet
HashSet 具有以下特点:
- 不能保证元素的排列顺序
- HashSet 不是线程安全的
- 集合元素可以是 null
HashSet 集合判断两个元素相等的标准: 两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
对于存放在Set容器中的对象, 对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即: “相等的对象必须具有相等的散列码” 。
重写 hashCode() 方法的基本原则
- 在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。
- 当两个对象的 equals() 方法比较返回true 时,这两个对象的 hashCode()方法的返回值也应相等。
- 对象中用作 equals() 方法比较的Field,都应该用来计算 hashCode 值
重写 equals() 方法的基本原则
以自定义的Customer类为例,何时需要重写equals()?
- 当一个类有自己特有的“逻辑相等”概念,当改写equals()的时候,总是要改写hashCode(),根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode()方法,它们仅仅是两个对象。
- 因此,违反了“相等的对象必须具有相等的散列码”。
- 结论:复写equals方法的时候一般都需要同时复写hashCode方法。通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算。
Set实现类之二:LinkedHashSet
-
LinkedHashSet 是 HashSet 的子类
-
LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用 双向链表维护元素的次序,这使得元素看起来是以 插入顺序保存的。
-
LinkedHashSet插入性能略低于 HashSet , 但在迭代访问 Set 里的全部元素时有很好的性能。
-
LinkedHashSet 不允许集合元素重复。
Set实现类之三:TreeSet
- 基于TreeMap
- TreeSet底层使用红黑树结构存储数据
- 特点:有序,查询速度比List快(有序指的是他的自然顺序)
所有的基本类型的包装类 及String类都实现了一个Comparable接口。
- 该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法 。
在list内取出重复数字值,要求尽量简单。
//方式一:
public static void main(String[] args) {
List list = new ArrayList ();
list.add(1);
list.add(2);
list.add(1);
list.add(4);
list.add(2);
List newList = new ArrayList();
for(Object obj : list) {
boolean flag = newList.contains(obj);
if(!flag) {
newList.add(obj);
}
}
list = newList;
for(Object obj : list) {
System.out.println(obj);
}
}
//方式二:利用Set集合的特点
public static void main(String[] args) {
List list = new ArrayList ();
list.add(1);
list.add(2);
list.add(1);
list.add(4);
list.add(2);
Set set = new HashSet();
for(Object obj : list) {
set.add(obj);
}
list.clear();
list.addAll(set);
for(Object obj : list) {
System.out.println(obj);
}
}