java TreeSet错误使用

与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的。在大神的Java提高篇(二七)—–TreeMap中详细讲解了TreeMap实现机制。这里只是介绍我的一个错误用法:

import java.util.Set;
import java.util.TreeSet;

/**
 * Created by mac on 2017/4/3.
 */
public class TreeSetTest implements Comparable<TreeSetTest> {
    int priority;
    String name;

    public TreeSetTest(int priority, String name) {
        this.priority = priority;
        this.name = name;
    }

    @Override
    public int compareTo(TreeSetTest o2) {
        if (name.equals(o2.name)) {
            return 0;
        }
        if (priority != o2.priority) {
            return priority - o2.priority;
        }
        return -1;
    }

    public static void main(String args[]) {
        Set<TreeSetTest> sets = new TreeSet();

        for (int j = 0; j < 10; j++) {
            for (int i = 0; i < 10; i++) {
                TreeSetTest treeMapTest=new TreeSetTest(0, i + "");

                if(!sets.contains(treeMapTest)){
                    sets.add(treeMapTest);
                }

            }
            System.out.println(sets.size());
        }
    }

}
 

输出结果是:

10
18
25
31
34
39
43
47
50
52

这个程序本来是想通过priority排序,但是name作为唯一识别字段,而同一个priority是无序的,结果试验结果与预期不一样。原因在TreeSet的contains()方法的实现上,最后调用了TreeMap的contaninsKey()函数:

public boolean containsKey(Object key) {
        return getEntry(key) != null;
 }

final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }

在这里contanis函数最后根据tree去判断对象是否在存在,当第一个TreeSetTest对象在第一次插入的时候它是最大的那个对象,第二次插入的时候,它和root去比较最后由于name不一致,直接去小的树枝去查找,最后必然找不到。
所以,使用TreeSet和TreeMap的时候,一定要保证数据是唯一有序的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,803评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,391评论 11 349
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,531评论 0 3
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,147评论 0 62
  • 在发布ASP.NET 网站时,一般都会用到IIS来发布,而windows系统本身就带有IIS,只是在默认情况下,将...
    func_老衲姓罗阅读 355评论 0 0