zoukankan      html  css  js  c++  java
  • HashSet

    HashSet基与HashMap

    源码

     public class HashSet<E> 
         extends AbstractSet<E> 
         implements Set<E>, Cloneable, java.io.Serializable 
     { 
         // 使用 HashMap 的 key 保存 HashSet 中所有元素
         private transient HashMap<E,Object> map; 
         // 定义一个虚拟的 Object 对象作为 HashMap 的 value 
         private static final Object PRESENT = new Object(); 
         ... 
         // 初始化 HashSet,底层会初始化一个 HashMap 
         public HashSet() 
         { 
             map = new HashMap<E,Object>(); 
         } 
         // 以指定的 initialCapacity、loadFactor 创建 HashSet 
         // 其实就是以相应的参数创建 HashMap 
         public HashSet(int initialCapacity, float loadFactor) 
         { 
             map = new HashMap<E,Object>(initialCapacity, loadFactor); 
         } 
         public HashSet(int initialCapacity) 
         { 
             map = new HashMap<E,Object>(initialCapacity); 
         } 
         HashSet(int initialCapacity, float loadFactor, boolean dummy) 
         { 
             map = new LinkedHashMap<E,Object>(initialCapacity 
                 , loadFactor); 
         } 
         // 调用 map 的 keySet 来返回所有的 key 
         public Iterator<E> iterator() 
         { 
             return map.keySet().iterator(); 
         } 
         // 调用 HashMap 的 size() 方法返回 Entry 的数量,就得到该 Set 里元素的个数
         public int size() 
         { 
             return map.size(); 
         } 
         // 调用 HashMap 的 isEmpty() 判断该 HashSet 是否为空,
         // 当 HashMap 为空时,对应的 HashSet 也为空
         public boolean isEmpty() 
         { 
             return map.isEmpty(); 
         } 
         // 调用 HashMap 的 containsKey 判断是否包含指定 key 
         //HashSet 的所有元素就是通过 HashMap 的 key 来保存的
         public boolean contains(Object o) 
         { 
             return map.containsKey(o); 
         } 
         // 将指定元素放入 HashSet 中,也就是将该元素作为 key 放入 HashMap 
         public boolean add(E e) 
         { 
             return map.put(e, PRESENT) == null; 
         } 
         // 调用 HashMap 的 remove 方法删除指定 Entry,也就删除了 HashSet 中对应的元素
         public boolean remove(Object o) 
         { 
             return map.remove(o)==PRESENT; 
         } 
         // 调用 Map 的 clear 方法清空所有 Entry,也就清空了 HashSet 中所有元素
         public void clear() 
         { 
             map.clear(); 
         } 
         ... 
     } 

    ,HashSet 的实现其实非常简单,它只是封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。

    由于HashSet的add()方法添加集合元素时实际转变为HashMap的put方法来添加key-value对,当新放入的HashSet的Entry中的key相同时(hashCode()的返回值相同,通过equal比较也返回true)时,新添加的Entry的value将value将覆盖原来的Entry的value,但key不会有任何改变,因此,如果向HashSet中添加一个已经存在的元素,新添加的集合元素不会覆盖已经有的集合元素。

    package example;
    
    import java.util.HashSet;
    import java.util.Set;
    
    class Base{
        private String name;
        private int age;
        public Base(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
        /*public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }*/
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Base other = (Base) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return name+age+"";
        }
        
    }
    
    public class Test  {
    
        public static void main(String[] args) {
            Set<Base> s=new HashSet<Base>();
            s.add(new Base("zhangsan",4));
            System.out.println(s.contains(new Base("zhangsan",4))); //打印false
        }
    
        
    
    }

    打印false的原因,HashSet判断两个对象相等的标准除了要求通过equals()方法比较返回true之外,还要

    两个对象的hashCode()返回值相等。因为上面类没有重写hashCode所以HashSet会把它当做两个对象。

  • 相关阅读:
    HBase 在HDFS上的物理目录结构
    Hbase-site.xml
    hbase-default.xml(Hbase 默认参数翻译)
    flink-conf.yaml
    Spark Standalone spark-default.conf
    Spark Standalone spark-env.sh
    windows linux 文件编码转换
    Hbase G1 gc 调优最终参数
    python
    python
  • 原文地址:https://www.cnblogs.com/xurui1995/p/5330796.html
Copyright © 2011-2022 走看看