`
zyz251314
  • 浏览: 5978 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

TreeSet排序丢失记录

    博客分类:
  • java
 
阅读更多

 昨天系统用户提示说查询到的记录少了,然后就开始进行各种纠结ing,查找源码,各种debug最后发现是在进入放入TreeSet的时候丢失了。

 

以下是定义的TreeSet

Set<Bill> set = new TreeSet<Bill>(new Comparator<Bill>() {
				public int compare(Bill o1, Bill o2)
				{
					String shopNo1 = o1.getShopSysNo();
					String shopNo2 = o2.getShopSysNo();
					if (shopNo1.compareTo(shopNo2) > 0)
						return 1;
					else if (shopNo1.compareTo(shopNo2) < 0)
						return -1;
					else if (shopNo1.compareTo(shopNo2) == 0) {
						String clearDate1 = o1.getClearDate();
						String clearDate2 = o2.getClearDate();
						return clearDate1.compareTo(clearDate2);
					}
					return 0;
				}
			});

 然后开始查看TreeSet的Add()的源码

 

public boolean add(E e) {return m.put(e, PRESENT)==null;}

 发现底层调用了TreeMap的put方法,继续追踪:

 

 

public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
	    // TBD:
	    // 5045147: (coll) Adding null to an empty TreeSet should
	    // throw NullPointerException
	    //
	    // compare(key, key); // type check
            root = new Entry<K,V>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<K,V>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

 发现当调用TreeSet的add()方法时,在TreeSet的内部会间接调用compareTo()方法、然后和TreeSet中已经存在的其他元素一一进行比较,在比较的过程中完成“判断是否重复”以及“排序”的功能:当在某次比较的过程中发现compareTo()返回0,就会认为待加入的元素已经存在于TreeSet中,返回-1或1的话就会根据TreeSet默认的比较器进行排序。

 

 

分享到:
评论

相关推荐

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     6.1 关系数据库按主键区分不同的记录  6.1.1 把主键定义为自动增长标识符类型  6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分...

    Java源码分析:集合-容器.pdf

    TreeSet利用二叉树的原理对元素进行排序,它可以将元素按照指定的顺序进行排序。如果需要对自定义对象进行排序,则要求该对象必须实现Comparable接口,并且正确覆写compareTo方法。LinkedHashSet是HashSet的一个子类...

    2021-2022计算机二级等级考试试题及答案No.4734.docx

    13. 线性表排序:冒泡排序在最坏情况下的比较次数为 n(n-1)/2,快速排序在最坏情况下也是 n(n-1)/2。 14. Internet 最广泛应用服务:WWW(World Wide Web)服务是最广泛的应用,提供网页浏览功能。 15. USB 接口:...

    2021-2022计算机二级等级考试试题及答案No.12471.docx

    **TreeSet**:是一个实现Set接口的类,用于存储不重复的元素,并按自然顺序排序。 - C. **Properties**:用于存储配置信息,通常用于读写.properties文件。 - D. **TreeMap**:是一个实现Map接口的类,用于存储...

    2021-2022计算机二级等级考试试题及答案No.5248.docx

    6. **TreeSet**:Java中的`TreeSet`是有序的集合,如果没有传入比较器,它会使用元素自然排序,或者元素必须实现`Comparable`接口以进行比较。 7. **交叉表查询**:在数据库中,交叉表查询用于统计不同类别的数据...

    《阿里巴巴Java工作手册》学习笔记

    例如,`ArrayList`提供有序但不排序的特性,而`TreeSet`则提供了排序且有序的特性。 - **空值处理**:不同类型的`Map`集合对于键(Key)和值(Value)是否支持`null`有不同的规定。了解这些细节有助于避免潜在的运行...

    2021-2022计算机二级等级考试试题及答案No.1389.docx

    - **详细解释**:在Java集合框架中,`TreeSet`是一个基于红黑树实现的集合类,它可以自动对元素进行排序,并且不允许重复元素的存在。 ### 18. 项目管理器的功能 - **知识点概述**:项目管理器用于组织和管理与...

    2021-2022计算机二级等级考试试题及答案No.16705.docx

    21. 创建TreeSet集合时,如果没有传入比较器,那么元素需要实现Comparable接口,以便进行排序。 22. 使用Option Explicit语句可以在VBA或Visual Basic中强制显式声明变量,避免未声明变量的错误。 23. 代码片段...

    2021-2022计算机二级等级考试试题及答案No.1480.docx

    10. 若要在一个集合中保存无重复且有序的元素,可以使用`TreeSet`,它基于红黑树数据结构,自动排序。 11. 当建立两个表之间的临时关系时,必须设置子表的主控索引,以关联两个表的数据。 12. 自然连接是一种SQL...

    2021-2022计算机二级等级考试试题及答案No.16205.docx

    - **默认比较器**:如果没有提供自定义的比较器,则TreeSet集合中的元素必须实现`Comparable`接口以支持自然排序。 ### 10. SQL语言中最常用的数据操纵语句 - **SELECT语句**:在SQL语言中,`SELECT`是最常用的...

    2021-2022计算机二级等级考试试题及答案No.1897.docx

    **解析**:题目要求集合中保存的元素无重复并按一定顺序排列,因此最适合的选择是**TreeSet**,因为它既能保持元素的唯一性又能按自然顺序或自定义比较器进行排序。选项**D**(TreeSet)是正确答案。 #### 标识符...

    2021-2022计算机二级等级考试试题及答案No.13013.docx

    - **TreeSet**: 类似于TreeMap,但它是基于NavigableSet接口的实现,主要用于存储唯一元素的集合,并按自然顺序或自定义比较器进行排序,不适合保存映射关系的数据。 ### 单选题:位运算 **题目**: 以下程序段...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     6.1 关系数据库按主键区分不同的记录  6.1.1 把主键定义为自动增长标识符类型  6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     6.1 关系数据库按主键区分不同的记录  6.1.1 把主键定义为自动增长标识符类型  6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     6.1 关系数据库按主键区分不同的记录  6.1.1 把主键定义为自动增长标识符类型  6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分...

Global site tag (gtag.js) - Google Analytics