打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java集合框架总结(3)
Java集合框架总结(3)——TreeSet类的排序问题?TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用

Java集合框架总结(3)——TreeSet类的排序问题

TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用自然排序。

1、自然排序

TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式就是自然排序。(比较的前提:两个对象的类型相同)。

java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现了该接口的类的对象就可以比较大小。当一个对象调用该方法与另一个对象进行比较,例如obj1.comparTo(obj2),如果该方法返回0,则表明这两个对象相等;如果返回一个正整数,则表明obj1大于obj2;如果该方法返回一个负整数,则表明obj1小于obj2.

java常用类实现Comparable接口,并提供了比较大小的标准。实现Comparable接口的常用类:

  • BigDecimal、BigIneger以及所有数值型对应包装类:按它们对应的数值的大小进行比较。
  • Character:按字符的UNICODE值进行比较。
  • Boolean:true对应的包装类实例大于false对应的包装类实例。
  • String:按字符串中字符的UNICODE值进行比较。
  • Date、Time:后面的时间、日期比前面的时间、日期大。

    如果试图把一个对象添加进TreeSet时,则该对象的类必须实现Comparable接口。

    如下程序则会报错:

    < }="" r(5)));="" hs.contains(new="" +="" system.out.println(?hs是否包含count为5的r对象??="" 输出false="" r(-3)));="" system.out.println(?hs是否包含count为-3的r对象??="" system.out.println(hs);="" r(-3));="" hs.remove(new="" 再次输出count将看到treeset里的元素处于无序状态="" first.count="-3;" 为第一个元素的count属性赋值="" first="(R)it.next();" r="" it="hs.iterator();" iterator="" 取出第一个元素="" 打印treeset集合,集合元素是有序排列的="" r(-2));="" hs.add(new="" r(9));="" r(5));="" hashset();="" hs="new" hashset="" {="" args)="" main(string[]="" void="" static="" public="" testhashset2="" this.count;="" return="" hashcode()="" int="" false;="" true;="" this.count)="" (r.count="=" if="" r="(R)obj;" r)="" instanceof="" (obj="" obj)="" equals(object="" boolean="" count="" name="code">

    程序运行结果:

    [R(count属性:-3), R(count属性:-2), R(count属性:5), R(count属性:9)]?
    [R(count属性:20), R(count属性:-2), R(count属性:5), R(count属性:-2)]?
    [R(count属性:20), R(count属性:-2), R(count属性:5), R(count属性:-2)]?
    [R(count属性:20), R(count属性:-2), R(count属性:-2)]

    说明:

    上面程序中的R对象是一个正常重写了equals方法和comparable方法类,这两个方法都以R对象的count属性作为判断的依据。可以看到程序第一次输出的结果是有序排列的。当改变R对象的count属性,程序的输出结果也发生了改变,而且包含了重复元素。一旦改变了TreeSet集合里可变元素的属性,当再视图删除该对象时,TreeSet也会删除失败(甚至集合中原有的、属性没被修改,但与修改后元素相等的元素也无法删除),所以删除count

    为-2的R对象时,没有任何元素被删除;程序可以删除count为5的R对象,这表明TreeSet可以删除没有被修改属性、且不与其他被修改属性的对象重复的对象。

    总结:与HashSet在处理这些对象时将非常复杂,而且容易出错。为了让程序更具健壮,推荐HashSet和TreeSet集合中只放入不可变对象。

    2、定制排序

    TreeSet的自然排序是根据集合元素的大小,TreeSet将他们以升序排列。如果需要实现定制排序,例如降序,则可以使用Comparator接口。该接口里包含一个int compare(T o1, T o2)方法,该方法用于比较o1和o2的大小。

    如果需要实现定制排序,则需要在创建TreeSet集合对象时,并提供一个Comparator对象与该TreeSet集合关联,由该Comparator对象负责集合元素的排序逻辑。

    如下程序所示:

    < }="" +="" {="" args)="" main(string[]="" void="" static="" public="" return="" int="" if="" name="code" system.out.println(ts);="" m(9));="" ts.add(new="" m(-3));="" m(5));="" });="" 1;="" else="" 0;="" m2.age)="" (m1.age="" -1;="" >="" o2;="" m2="(M)" m="" o1;="" m1="(M)" o2)="" object="" o1,="" compare(object="" comparator()="" treeset(new="" ts="new" treeset="" testtreeset3="" }public="" age="">

    程序运行结果:

    [M对象(age:9), M对象(age:5), M对象(age:-3)]

    说明:

    上面程序中创建了一个Comparator接口的匿名内部类对象,该对象负责ts集合的排序。所以当我们把M对象添加到ts集合中时,无须M类实现Comparable接口,因为此时TreeSet无须通过M对象来比较大小,而是由与TreeSet关联的Comparator对象来负责集合元素的排序。使用定制排序时,TreeSet对集合元素排序时不管集合元素本身的大小,而是由Comparator对象负责集合元素的排序规则。

    编辑推荐图片

    Chrome开发debug

    • 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
      打开APP,阅读全文并永久保存 查看更多类似文章
      猜你喜欢
      类似文章
      【热】打开小程序,算一算2024你的财运
      HashSet 与TreeSet和LinkedHashSet的区别
      Java集合总结:Set集合
      JAVA集合类(介绍)
      Java容器类学习心得,欢迎拍砖
      Java Set集合的详解
      java中set接口使用方法详解
      更多类似文章 >>
      生活服务
      热点新闻
      分享 收藏 导长图 关注 下载文章
      绑定账号成功
      后续可登录账号畅享VIP特权!
      如果VIP功能使用有故障,
      可点击这里联系客服!

      联系客服