Set接口常用方法:

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
       //牛不牛
  }

}