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)。
  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/crelle/p/13658405.html
Copyright © 2011-2022 走看看