/* 看一下部分的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; } }
HashSet中实现不插入重复的元素
时间: 2024-10-11 13:21:03