Set集合:

无序,不允许重复

public interface Set<E> extends Collection<E>

set接口中的所有方法都继承于Collection接口,没有新方法

允许使用null元素。

这里没有什么新方法,只对 add()、equals() 和 hashCode() 方法添加了限制

  不允许重复

规则:先判断两个元素对象的hashCode值是否相等,如果相等再调用equals进行等值判断,如果相等则丢弃

如果两个元素对象的hashCode值不相等,则不会调用equals方法,直接进行添加

HashSet和TreeSet是Set的实现

Set接口—>HashSet实现类 --> LinkedHashSet【在hashSet的基础上给每个存储的元素额外添加一个链表,用于记录添加元素的顺序】

SortedSet —> TreeSet

HashSet的后台有一个HashMap;初始化后台容量;只不过生成一个HashSet的话,系统只提供key的访问; 如果有两个Key重复,那么会覆盖之前的;

实现类 :

  • HashSet:equals返回true,hashCode返回相同的整数;哈希表;存储的数据是无序的。
  • LinkedHashSet:此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。 存储的数据是有序的。

HashSet的实现原理

public class HashSet<E>
    extends AbstractSet<E>  抽象类,其中提供Set的公共方法
    implements Set<E>,  实现Set接口   Set set=new HashSet(); 多态
     	Cloneable,可克隆的
     	 java.io.Serializable  可序列化和反序列化的

属性:

private transient HashMap<E,Object> map; 具体存储数据的HashMap,存储数据需
要提供key和value两个部分,HashSet只是使用了key值部分
  
  private static final Object PRESENT = new Object(); 在HashMap中所有的value值

Hash一般翻译为“散列”,也有直接音译为“哈希”的,这就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值);这种转换是一种压缩映射,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值

简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。 md5

MessageDigest md=MessageDigest.getInstance("md5");
String pwd="123456";
byte[] bb=md.digest(pwd.getBytes());
String ss=Base64.getEncoder().encodeToString(bb);
System.out.println(ss);

所有散列函数都有如下一个基本特性:

根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同。

构造器

public HashSet() {
        map = new HashMap<>();
    }
    
     public HashSet(int initialCapacity初始化容器, float loadFactor负载因子) {  集合中最大存储数据的数据
     量为【容器*负载因子】,如果大于这个值则自动扩容
        map = new HashMap<>(initialCapacity, loadFactor);
    }

哈希冲突

当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,就把它叫做碰撞(哈希碰撞)。

以key/value的方式存储数据,采用拉链法综合了数组和链表结构。如果key已知则存取效率较高,但是删除慢,如果不知道key存取则慢,对存储空间使用不充分。最典型的实现是HashMap。

public HashSet(int initialCapacity初始化容积,默认负载0.75) {
        map = new HashMap<>(initialCapacity);
    }

添加方法 add

public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

删除方法remove

public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

LinkedHashSet

类定义

public class LinkedHashSet<E>
    extends HashSet<E>  继承于HashSet
    implements Set<E>, Cloneable, java.io.Serializable {

具体的存储实现和HashSet一致,具体实现为LinkedHashMap

public LinkedHashSet() {
        super(16, .75f, true); 初始化容积16,负载因子0.75,
    }
    
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }