HashSet和TreeSet去重机制

76 阅读1分钟

HashSet去重机制

HashSet底层实现为HashMap

public HashSet() {
    map = new HashMap<>();
}

去重机制:hashCode() + equals()

1、先通过传入的对象,运算得到一个hash值

// HashSet 的 add 方法
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

// HashMap中的 put 方法
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
// HashMap 中的 hash 运算机制
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

2、通过hahs值得到对应索引

tab[i = (n - 1) & hash]

3、如果table数组中索引所在的位置没有数据,直接存放;如果有数据,遍历进行equals比较,如果为false,就加入,否则不加入,详细比较方法可以看HashMap源码的“putVal”方法

TreeSet去重机制

TreeSet底层实现为TreeMap

public TreeSet() {
    this(new TreeMap<E,Object>());
}


public TreeSet(Comparator<? super E> comparator) {
    this(new TreeMap<>(comparator));
}

去重机制:compare 方法

1、如果传入一个 Comparator匿名对象,就使用实现的compare方法去重,如果返回值为0,则认为是相同元素,不添加

TreeSet treeSet = new TreeSet(new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
        return ((String)o1).compareTo((String)o2);
    }
});

2、如果没有传入一个Comparator匿名对象,则以添加对象实现的Compareable接口的compareTo方法去重

// 例子
// 添加的是String类型的元素数据
// String实现了 Comparable<String>接口,根据java的多态绑定机制,会走String 的 compareTo 方法
TreeSet treeSet = new TreeSet();
treeSet.add("Hello Word");

// String 类的源码,实现了Comparable接口
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence