有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java HashMap和HashSet有什么共同点?

在任何地方,你都可以找到答案,区别是什么:

Map正在存储键值,它不是同步的(不是线程安全的),允许空值和一个空键,因为所有值都有唯一的键,所以获取值的速度更快,等等。 集合-未排序,获取值较慢,仅存储值,不允许重复或空值

但是Hash单词的意思是什么(这就是它们的相同之处)。是关于散列值还是其他我希望你能清楚回答我的问题


共 (6) 个答案

  1. # 1 楼答案

    HashSet就像一个HashMap,您不关心值,只关心键。 因此,您只关心给定的键K是否在集合中,而不关心它映射到的值V(您可以将其视为V是常数,例如,对于HashSet中的所有键,V=Boolean.TRUE)。所以HashSet没有值(V set)。从结构的角度来看,这就是整个差异。散列部分意味着,当将元素放入结构中时,Java首先调用hashCode方法。参见http://en.wikipedia.org/wiki/Open_addressing了解发动机罩下发生的一般情况

    哈希值用于更快地检查两个对象是否相同。如果两个对象具有相同的散列,那么它们可以相等,也可以不相等(因此,使用equals方法比较它们是否相等)。但是如果它们有不同的散列,它们肯定是不同的,不需要检查是否相等。这并不意味着,如果两个对象具有相同的哈希值,那么当它们存储在HashSet或HashMap中时,它们会相互覆盖。

  2. # 2 楼答案

    HashSetHashMap有许多共同点:

    1. 他们名字的开头——这是真正相似之处的线索
    2. 它们使用散列代码(来自所有Java对象中内置的hashCode方法)来快速处理和组织对象
    3. 它们都是无序集合,但都提供有序变量(LinkedHashX以按加法顺序存储对象)
    4. 还有TreeSet/TreeMap对集合中存在的所有对象进行排序并保持它们的排序。将TreeSet与TreeMap进行比较,会发现HashSet和HashMap之间存在非常相似的差异和相似之处

    一般来说,它们都受到散列算法的优势和局限性的影响

    1. 只有当对象具有性能良好的哈希函数时,哈希才有效
    2. 如果equalshashCode没有遵循正确的约定,哈希将完全中断
    3. 地图中的关键对象和集合中的对象应该是不可变的(或者至少它们的hashCodeequals返回值永远不应该更改),否则行为将变得未定义

    如果查看Map API,还可以看到许多其他有趣的连接,例如keySetentrySet都返回Set

    没有一个Java集合是线程安全的。其他软件包中的一些较旧的类已被删除,但它们大多已退役。对于线程安全,请查看concurrent包;对于非线程安全,请查看collections

  3. # 3 楼答案

    两者都不是Thread安全的,使用hashCode()存储值。这些都是常见的事实。另一个是,他们都是Java集合框架的成员。但这两者之间有很多不同之处

  4. # 4 楼答案

    只要看看HashSet{a1},你就会看到它使用HashMap。因此,它们具有相同的空安全性、同步性等属性:

    public class HashSet<E>
    
    ...
    
        private transient HashMap<E,Object> map;
    
        // Dummy value to associate with an Object in the backing Map
        private static final Object PRESENT = new Object();
    
        /**
         * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
         * default initial capacity (16) and load factor (0.75).
         */
        public HashSet() {
            map = new HashMap<>();
        }
    
    ...
    
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
    
    ...
    
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
    
    ...
    
    }
    
  5. # 5 楼答案

    Hash是用来将密钥转换为索引的技术。回到data Structures类,我们曾经学习如何构造哈希表,要做到这一点,您需要获取作为值插入的字符串,并将其转换为数字,以索引内部用作存储数据结构的数组

    有一个问题也被讨论得很透彻,那就是找到一个哈希函数,它会产生最小的冲突,这样我们就不会有两个不同的对象,不同的键共享同一个位置

    因此,散列是关于如何处理密钥以进行存储。如果我们想一想,没有一种(真正的)方法可以用字符串来索引内存,只有用数字,所以要有一个2d结构,比如一个由字符串(或者你想要的对象)索引的表,你需要为该字符串生成一个数(或者散列),并将值存储在这个索引的数组中。但是,如果需要键“name”,则需要在同一索引中使用不同的数组来存储键“name”

    干杯

  6. # 6 楼答案

    两者都使用对象的哈希值来存储,该值在内部使用对象类的hashCode();方法

    因此,如果要存储自定义类的实例,则需要重写hashCode();方法