Set的无序和不可重复的理解:
以HashSet为例:
无序性: 不等于随机性,存储的数据在底层结构并不是按照数组索引的书序来添加,而是根据数据的哈希值来添加。
不可重复性: 保证添加的元素按照equals()来判断时,不能返回true;即:相同的元素只能添加一个
添加过程: 向HashSet中添加元素a,首先调用元素a所在类的hashCode方法,计算a的哈希值,此哈希值接着通过某种算法计算出a在HashSet底层数组中的存放位置(即索引位置),判断数组此位置上是否已经有元素,若添加位置为空,直接添加即可;位置不为空,为链表或者单元素,则比较hash值,不一致则添加,一致则调用equals方法比较,结果为false则添加。
对于已经有元素后添加成功的情况来说,元素a与已经存在的指定索引位置上数据以链表方式存储。
对于链表方向:
jdk 7: a指向原来的元素
jdk 8: 原来的元素指向a 即七上八下
Nocice:
向Set中添加的数据,其所在的一定要重写equals和hashCode方法,且重写的hashCode和equals方法尽可能保持一致性。(相等的对象必须具有相等的散列码)
package com.cheng.collection;
import org.junit.Test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Settest {
//Collection :单列集合用来存储一个一个的数据
//Set接口:存储无序的、不可重复的数据
// HashSet:set接口的主要实现类,线程不安全,可以存储null
// LinkedHashSet:是HashSet的子类,可以按照其添加的顺序遍历内部数据
// TreeSet:可以按照添加对象的指定属性进行排序
@Test
public void test1(){
Set set = new HashSet();
set.add(123);
set.add(456);
set.add("牛不牛");
set.add(new Person("Jerry",56));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//输出结果:
//Person{name='Jerry', age=56}
//456
//123
//牛不牛
}
}