zoukankan      html  css  js  c++  java
  • HashSet中实现不插入重复的元素

    /*
    看一下部分的HashSet源码....
    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
    
        private transient HashMap<E,Object> map;
    
        private static final Object PRESENT = new Object();
        public HashSet() {
            map = new HashMap<>();
        }
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
        }
    
        public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
        }
        public HashSet(int initialCapacity) {
            map = new HashMap<>(initialCapacity);
        }
    
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
    
        public Iterator<E> iterator() {
            return map.keySet().iterator();
        }
    
    
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;//在下面的代码中我们可以看见map.put()的代码
        }
    }
    
    public class HashMap<K,V>
        extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable
    {
         .....
         final int hash(Object k) {
            int h = 0;
            if (useAltHashing) {
                if (k instanceof String) {
                    return sun.misc.Hashing.stringHash32((String) k);
                }
                h = hashSeed;
            }
    
            h ^= k.hashCode();//调用了改对象中的hashCode()方法,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    
         public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key);//调用了上面的函数
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }
    
            modCount++;
            addEntry(hash, key, value, i);
            return null;
        }
    }
    
    也就是说HashSet内部实现使用HashMap这个类来完成的
    TreeSet的内部实现元素之间是否相等?
    从上面的比较方法中可以看出,只有两个对象的hash值相等并且对象的内容也想等,那么两个对象才相等
    并且判断的方法用的是 equals 方法
    注意:当equals()此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
    */
    
    import java.util.*;
    public class CompTest{
        public static void main(String args[]){
            Set<myClass> st = new HashSet<myClass>();
            st.add(new myClass(1, "fd"));
            st.add(new myClass(2, "fff"));
            st.add(new myClass(2, "tttt"));
            st.add(new myClass(1, "fd"));
    
            for(Iterator<myClass> it = st.iterator(); it.hasNext();)
                System.out.println(it.next());
        }
    }
    
    class myClass{
    
       public int x;
       public String name;
       public myClass(int x, String name){
           this.x=x;
           this.name=name;
       }
       public int hashCode(){
          return x;
       }
    
       public boolean equals(Object tmp){//这里是方法的重写,参数的类型和个数一定要一样....
           return x==((myClass)tmp).x && name.equals( ((myClass)tmp).name);
       }
       public String toString(){
          return x+" "+name;
       }
    }
    

      

  • 相关阅读:
    一次安装。net core的经历
    c# task 等待所有子线程执行完的写法
    .net 中的async,await理解
    dbeaver pgsql连接工具
    oracle 导出表结构和备注
    abp
    发布站点
    excel 拆分多个excel并保持
    重定向和反向代理的区别
    es6中的解构赋值
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/3815257.html
Copyright © 2011-2022 走看看