• 基于hash算法的三个集合HashTable,HashSet和HashMap详解


    位运算符

    下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:

    public class Test {
      public static void main(String[] args) {
         int a = 60; /* 60 = 0011 1100 */ 
         int b = 13; /* 13 = 0000 1101 */
         int c = 0;
         c = a & b;       /* 12 = 0000 1100 */
         System.out.println("a & b = " + c );
     
         c = a | b;       /* 61 = 0011 1101 */
         System.out.println("a | b = " + c );
     
         c = a ^ b;       /* 49 = 0011 0001 */
         System.out.println("a ^ b = " + c );
     
         c = ~a;          /*-61 = 1100 0011 */
         System.out.println("~a = " + c );
     
         c = a << 2;     /* 240 = 1111 0000 */
         System.out.println("a << 2 = " + c );
     
         c = a >> 2;     /* 15 = 1111 */
         System.out.println("a >> 2  = " + c );
      
         c = a >>> 2;     /* 15 = 0000 1111 */
         System.out.println("a >>> 2 = " + c );
      }
    } 

    Hashtable和HashMap  

          区别一:继承的父类不同


      Hashtable 继承自 Dictionary 类,而 HashMap 继承自AbstractMap 类。但二者都实现了 Map 接口。


      区别二:线程安全性不同


      Hashtable 中的方法是 Synchronize 的,而 HashMap 中的方法在缺省情况下是非 Synchronize 的。


      区别三:是否提供 contains 方法


      HashMap 把 Hashtable 的 contains 方法去掉了,改成containsValue 和 containsKey,因为 contains 方法容易让人引起误解。
      Hashtable 则保留了 contains,containsValue 和 containsKey三个方法,其中 contains 和 containsValue 功能相同。


      区别四:**key 和 value 是否允许 null 值 (面试比较喜欢问)


      其中 key 和 value 都是对象,并且不能包含重复 key,但可以包含重复的 value。


      Hashtable 中,key 和 value 都不允许出现 null 值。


      HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null。当 get()方法返回 null值时,可能是 HashMap 中没有该键,也可能使该键所对应的值为 null。因此,在 HashMap 中不能由 get()方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey()方法来判断。


      区别五:哈希值的计算方法不同

           Hashtable 直接使用的是对象的 hashCode,而 HashMap 则是在对象的 hashCode 的基础上还进行了一些变化。

        static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }

      区别六:内部实现使用的数组初始化和扩容方式不同


      内存初始大小不同,HashTable 初始大小是 11,而 HashMap 初始大小是 16

    HashMap和HashSet区别

    //HashSet底层用来存储元素的结构,实际上使用HashMap来存储
    private transient HashMap<E,Object> map;
     
    //HashMap中的value值,HashSet只关注key值,所以所有的value值都为Object对象
    private static final Object PRESENT = new Object();
     
     
    //HashSet的无参构造,直接创建了一个HashMap对象
    public HashSet() {
            map = new HashMap<>();
    }
     
    //指定初始化容量和负载因子
    public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
    }
     
    //给定初始化容量
    public HashSet(int initialCapacity) {
            map = new HashMap<>(initialCapacity);
    }
     
    public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
    }

    可以看到 HashSet的构造方法底层都是调用 HashMap的构造方法, 所以HashSet底层实际上是使用 HashMap 来作为存储结构.

    当使用无参构造创建 HashSet对象时, 其实调用了 HashMap的无参构造创建了一个 HashMap对象, 所以 HashSet 的初始化容量也为16, 负载因子也为 0.75.

    再来看看 HashSet 的 add() 方法的实现:

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

    可以看到 HashSet 的 add() 方法底层实际也是调用了 HashMap 的 put() 方法, 这里的key为我们传入的将要添加到 set集合中的元素, 而value值则为 PERSENT,其实就是上面分析的 HashSet类中的一个静态字段, 默认为 Object对象.

    HashSet并不关注value元素, 只使用 HashMap来存储 key元素, 这就使得 HashSet判断元素相等的条件与 HashMap中 key相等的条件其实是一样的, 两个元素的 hashCode值相同且通过equals()方法比较返回 true.

    所以HashSet应该重写 equals()和hashCode()方法, 两个元素的 HashCode相同, 保证通过equals() 方法比较返回 true.

    总结一下HashSet和HashMap的区别:
    (1)HashSet实现了Set接口, 仅存储对象; HashMap实现了 Map接口, 存储的是键值对.

    (2)HashSet底层其实是用HashMap实现存储的, HashSet封装了一系列HashMap的方法. 依靠HashMap来存储元素值,(利用hashMap的key键进行存储), 而value值默认为Object对象. 所以HashSet也不允许出现重复值, 判断标准和HashMap判断标准相同, 两个元素的hashCode相等并且通过equals()方法返回true.

  • 相关阅读:
    献给 Python 开发人员的 25 个最佳 GitHub 代码库!
    6 drf-认证权限解析频率
    4: drf视图组件
    3 drf请求与响应
    十三:Django框架学习之auth模块
    十二:django中间件学习之拓展1
    git光速从入门到精通
    mac系统下的mysql安装(ver.8.0.20)
    python小练习——2048
    docker下overlay2占用空间过大,清理docker占用空间
  • 原文地址:https://www.cnblogs.com/qfdy123/p/16135739.html
Copyright © 2020-2023  润新知