zoukankan      html  css  js  c++  java
  • Java中HashSet的解读


    一. HashSet源代码 
    HashSet 的实现  
     
    对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:  Java代码  
    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 的绝大部分方法都是通过调用 HashMap 的方法来实现的,因此 HashSet 和 HashMap 两个集合在实现本质上是相同的。 


    二.HashSet<E>对象 
    HashSet<E>创建的对象称为集合: 
    HashSet<string> s= HashSet<string>; 
    那么s就是一个可以存储 string 类型数据的集合,s 可以调用add(String  s)方法将string类型的数据添加到集合中。添加到集合中的数据称为集合的元素。集合不允许有相同的元素,也就是说,如果b已经是集合中的元素,那么在执行set.add(b)操作是无效的。 三.HashSet<E>中的方法详解 
    ① public boolean add(E o) —— 向集合添加参数指定的元素。(如果此集合中还
    不包含指定元素,则添加指定元素。) 
          参数: 
    o - 将添加到此集合中的元素。  返回: 
    如果该集合还不包含指定元素,则返回 true。 
     
    ② public void clear() ——清空集合,使集合不含有任何元素。 
    ③ public boolean contains(Object o) —— 判断参数指定的数据是否属于集合。() 
    参数:  
    o - 其在此集合中的存在已得到测试的元素。  
    返回:  
    如果此集合不包含指定元素,则返回 true。 
    ④ public boolean isEmpty()—— 判断集合是否为空。 
    返回:  
    如果此集合不包含任何元素,则返回 true。 
    ⑤ public boolean remove(Object o) ——集合删除参数指定的元素。 
    参数:  
    o - 如果存在于此集合中则需要将其移除的对象。  
    返回:  
    如果集合包含指定元素,则返回 true。 
    ⑥ public int size () —— 返回集合中元素的个数。 
    返回:  
    此集合中的元素的数量(集合的容量)。 
    ⑦ Object [ ] toArray() —— 将集合元素存放到数组中,并返回这个数组。 
    ⑧ boolean containsAll (HashSet set) —— 判断当前集合是否包含参数指定的集合。 
    ⑨ public Object clone () —— 得到当前集合的一个克隆对象,该对象中元素的改
    变不会影响到当前集合中的元素,反之亦然。 返回:  
    此集合的浅表复制。 
     
    四.代码: 


    import java.util.HashSet;   
    class Student{       String name;       int score;   
        Student(String name, int score){           this.name = name;           this.score = score;       }   }   
    public class TestHashSet{      
        public static void main(String[] args) {   
            Student zh = new Student("张三",77);           Student li = new Student("李四",68);           Student wa = new Student("王五",67);              
            HashSet<Student> set = new HashSet<Student>();           HashSet<Student> subset = new HashSet<Student>();            
            System.out.println("Before add(zh):"+set.add(zh));             set.add(zh);  
            System.out.println("After  add(zh):"+set.add(zh));   //add方法的实现         set.add(wa);           set.add(li);              
            subset.add(wa);           subset.add(li);   
            System.out.println("Is subset empty?  "+subset.isEmpty()); //isempty方法的实现          
            if (set.contains(wa)){   
                System.out.println("集合set中含有:"+wa.name);  //contains方法的实现         }          
            if(set.containsAll(subset)){   
                System.out.println("集合set包含集合subset");           }            
            int number = subset.size();               //size方法的实现         System.out.println("集合subset中有"+number+"个元素:");            
            Object s[] = subset.toArray();            //toArray 方法的实现 


             
            for(int i=0; i<s.length; i++){   
                System.out.printf("姓名:%s,分数:%d ", ((Student)s[i]).name,((Student)s[i]).score);           }          
            subset.remove(wa);                       //remove方法的实现         System.out.println("After implement remove on subset");  
            System.out.println("集合subset中有"+subset.size()+"个元素:");          
            Object a[] = subset.toArray();                  
            for(int i=0; i<a.length; i++){   
                System.out.printf("姓名:%s,分数:%d ", ((Student)a[i]).name,((Student)a[i]).score);           }       }   } 
    五.运行结果  
    Before add(zh):true After  add(zh):false Is subset empty?  false 集合set中含有:王五 集合set包含集合subset 集合subset中有2个元素: 姓名:李四,分数:68 姓名:王五,分数:67 
    After implement remove on subset 集合subset中有1个元素: 姓名:李四,分数:68 

  • 相关阅读:
    oracle列合并
    Java移位操作符
    angularjs 事件向上向下传播
    angularjs 路由 ngRoute tab切换
    angularjs 自定义服务
    angularjs 服务供应商
    angularjs 缓存 $q
    angularjs $location 服务
    angularjs $http 服务
    angularjs 自定义指令 directive
  • 原文地址:https://www.cnblogs.com/dyc-cfc/p/4255644.html
Copyright © 2011-2022 走看看