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){<span style="color: #ff0000;">//这里是方法的重写,参数的类型和个数一定要一样....</span>
       return x==((myClass)tmp).x && name.equals( ((myClass)tmp).name);
   }
   public String toString(){
      return x+" "+name;
   }
}

目录
相关文章
|
27天前
|
算法 测试技术 C#
【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
|
5月前
判断两个不重复的list集合是否相等 只比较元素值 不比较顺序
判断两个不重复的list集合是否相等 只比较元素值 不比较顺序
26 0
|
9月前
List 集合去除重复元素的5种方法
List 集合去除重复元素的5种方法
177 0
|
11月前
逆序遍历List集合
逆序遍历List集合
40 0
|
JavaScript 小程序 Java
HashMap 为什么不能一边遍历一遍删除
HashMap 为什么不能一边遍历一遍删除
|
Shell
List有序可重复,Set无序不重复!
List有序可重复,Set无序不重复,这里指的是添加数据的顺序。
141 0
List有序可重复,Set无序不重复!
记录插入顺序用linkedHashMap
记录插入顺序用linkedHashMap
87 0
|
安全 Java 容器
如何在遍历的同时删除ArrayList 中的元素
如何在遍历的同时删除ArrayList 中的元素
354 0
|
安全 Java 编译器
删除list集合中特定元素的正确姿势
删除list集合中特定元素的正确姿势
439 0