JavaSE-15.1.3【HashSet集合的特点和保证元素唯一性的原理、常见数据结构之哈希表】

 

 

 

 

  1 package day6.lesson1;
  2 
  3 import java.util.HashSet;
  4 
  5 /*
  6 1.3 HashSet集合的特点
  7 
  8     底层数据结构是哈希表
  9     对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
 10     没有带索引的方法,所以不能使用普通for循环遍历(但可以使用迭代器和增强for进行遍历)
 11     由于是Set集合,所以是不包含重复元素的集合
 12 
 13 1.4 HashSet集合保证元素唯一性的原理
 14 
 15     图示
 16 
 17     1.根据对象的哈希值计算存储位置
 18         如果当前位置没有元素则直接存入
 19         如果当前位置有元素存在,则进入第二步
 20     2.当前元素的元素和已经存在的元素比较哈希值
 21         如果哈希值不同,则将当前元素进行存储
 22         如果哈希值相同,则进入第三步
 23     3.通过equals()方法比较两个元素的内容
 24         如果内容不相同,则将当前元素进行存储
 25         如果内容相同,则不存储当前元素
 26 
 27     总结:HashSet集合存储元素时要保证元素唯一性需要重写hashCode() & equals()
 28 
 29 1.5 常见数据结构之哈希表
 30 
 31     JDK8之前,哈希表采用数组+链表实现,即一个元素为链表的数组
 32     JDK8以后,在长度较长时,底层实现了优化 。。。
 33 
 34     哈希表图示,证明如何保证元素唯一性
 35  */
 36 public class HashSetDemo3 {
 37     public static void main(String[] args) {
 38         HashSet<String> hs = new HashSet<>();
 39         hs.add("hello");
 40         hs.add("world");
 41         hs.add("world");
 42         hs.add("java");
 43         hs.add("java");
 44         System.out.println(hs); //[world, java, hello]
 45         for (String str: hs){
 46             System.out.println(str);
 47         }
 48         /*
 49         world
 50         java
 51         hello
 52          */
 53 
 54         /*
 55         //add()溯源
 56         public boolean add(E e) {
 57             return map.put(e, PRESENT)==null;
 58         }
 59         public V put(K key, V value) {
 60             return putVal(hash(key), key, value, false, true);
 61         }
 62         static final int hash(Object key) {
 63             int h;
 64             return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
 65         }
 66         final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
 67                    boolean evict) {
 68             Node<K,V>[] tab;  //元素为节点的数组,哈希表
 69             Node<K,V> p;
 70             int n, i;
 71             if ((tab = table) == null || (n = tab.length) == 0)
 72                 n = (tab = resize()).length;
 73             if ((p = tab[i = (n - 1) & hash]) == null)
 74                 tab[i] = newNode(hash, key, value, null);
 75             else {
 76                 Node<K,V> e; K k;
 77                 if (p.hash == hash &&
 78                     ((k = p.key) == key || (key != null && key.equals(k))))
 79                     e = p;
 80                 else if (p instanceof TreeNode)
 81                     e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
 82                 else {
 83                     for (int binCount = 0; ; ++binCount) {
 84                         if ((e = p.next) == null) {
 85                             p.next = newNode(hash, key, value, null);
 86                             if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
 87                                 treeifyBin(tab, hash);
 88                             break;
 89                         }
 90                         if (e.hash == hash &&
 91                             ((k = e.key) == key || (key != null && key.equals(k))))
 92                             break;
 93                         p = e;
 94                     }
 95                 }
 96                 if (e != null) { // existing mapping for key
 97                     V oldValue = e.value;
 98                     if (!onlyIfAbsent || oldValue == null)
 99                         e.value = value;
100                     afterNodeAccess(e);
101                     return oldValue;
102                 }
103             }
104             ++modCount;
105             if (++size > threshold)
106                 resize();
107             afterNodeInsertion(evict);
108             return null;
109         }
110          */
111     }
112 }

 

posted @ 2021-05-31 21:24  yub4by  阅读(130)  评论(0编辑  收藏  举报