zoukankan      html  css  js  c++  java
  • Java中Set/HashSet的内部处理

    众所周知,集合是定义明确的不同对象的集合。集合的每个成员称为集合的元素。因此,换句话说,我们可以说一个集合永远不会包含重复的元素。但是如何在Java Set接口中实现的类(例如HashSet,LinkedHashSet,TreeSet等)实现这种唯一性。在本文中,我们将讨论这种独特性背后的隐藏真理。

    HashSet如何在Java内部工作?

    Set/HashSet在Java中的内部工作原理
    让我们看看下面这个程序的输出中有哪些元素是重复的。

    // Java program to demonstrate 
    // internal working of HashSet 
    
    import java.util.HashSet; 
    
    class Test 
    {     
        public static void main(String args[]) 
        { 
            // creating a HashSet 
            HashSet hs = new HashSet(); 
            
            // adding elements to hashset 
            // using add() method 
            boolean b1 = hs.add("Geeks"); 
            boolean b2 = hs.add("GeeksforGeeks"); 
            
            // adding duplicate element 
            boolean b3 = hs.add("Geeks"); 
            
            // printing b1, b2, b3 
            System.out.println("b1 = "+b1); 
            System.out.println("b2 = "+b2); 
            System.out.println("b3 = "+b3); 
            
            // printing all elements of hashset 
            System.out.println(hs); 
                
        } 
    } 

    输出:

    b1 = true
    b2 = true
    b3 = false
    [GeeksforGeeks, Geeks]

    现在从输出中可以清楚地看到,当我们尝试使用add()方法添加相同的元素时,则返回false,元素未添加到hashset中,因为它已经存在。现在问题来了,怎么做add()方法检查集合是否已包含指定元素。如果我们仔细看看add()方法就会发现它定义了HashSet类中的默认构造函数。

    // predefined HashSet class
    public class HashSet
    {
        // A HashMap object 
        private transient HashMap map;
    
        // A Dummy value(PRESENT) to associate with an Object in the Map
        private static final Object PRESENT = new Object();
        
        // default constructor of HashSet class
        // It creates a HashMap by calling 
        // default constructor of HashMap class
        public HashSet() {
            map = new HashMap<>();
        }
    
        // add method 
        // it calls put() method on map object
        // and then compares it's return value with null
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
     
        // Other methods in Hash Set
    }

    现在可以看到,每当我们创建一个HashSet时,它在内部创建一个HashMap,如果我们使用add()方法,它实际上调用了HashMap的put()方法,key为我们要设置的值,value为一个常量对象“PRESENT”,所以我们可知HashSet通过内部的HashMap存储唯一的值。

    那么问题来了?HashMap的put()方法内部是怎么实现的呢?

    我们知道HashMap每个key都是独一无二的,put(key,value)方法,则返回与键关联的上一个值,或者null如果没有键的映射。因此,在HashSet的add()方法中,我们使用null检查map.put(key,value)方法的返回值。

    1. 如果map.put(key,value)返回null,则语句“map.put(e,PRESENT)==null”返回true,元素被添加到HashSet(内部HashMap)。
    2. 如果map.put(key,value)返回key对应的value,那么语句“map.put(e,PRESENT)==null”将返回false,元素未添加到HashSet(内部HashMap)。
  • 相关阅读:
    react.js 你应知道的9件事
    table的border-collapse属性与border-spacing属性
    深入理解 CSS变形 transform(3d)
    $ 的绑定事件
    保留两位小数
    数据库日期格式化
    javaScript对两个数组进行去重
    js中的原型链__proto__其实超简单!!
    JSON.parse()和JSON.stringify()应用理解
    Java Web 重归
  • 原文地址:https://www.cnblogs.com/crelle/p/13658405.html
Copyright © 2011-2022 走看看