zoukankan      html  css  js  c++  java
  • JAVA-初步认识-常用对象API(集合框架-treeset集合)

    一.

    接下来讲解set中的常用子类treeset,演示一下treeset的特点。

    集合讲述到这里,谈论的都是不同集合内部的数据结构。

    这里必须采用迭代器输出,输出的结果是无序的。看到的存进去和取出来的是不一致的,但是取出来的结果有些规律,按照字符的首字母排序来输出。

    这个我们不称之为有序,是有指定顺序,按照元素的字典顺序排列。

    看下treeset的特点,

    既然我们往里面存了一些字符串了,输出的时候,也按照字典的顺序排列完了。下面就要存储一些自定义对象。

    结果显示错误,(按照之前的写法出错),类型转换异常。

    第19行,wangwu出现了错误。如果只保留zhangsan那一行,结果没有问题。保留两行还是出错,

    treeset集合干嘛的?给元素排序用的,排序就必然意味着比较。只存一个对象,不用比较。存两个对象就要比较。

    保留两行的时候,比不了,因为这个person类没有比较功能。有人说写了equals,这里需要的是比较,而不是判断相同。比较是要分大小的,情况不是两种,是三种的。

    我们现在看一下,java.lang.Comparable到底是什么。

    读了上面的截图,有什么感受?person正常描述人这类事物,该有什么描述什么。描述完了以后,我现在要把person放到treeset集合中进行排序。你觉得person

    是不是应该在已具备的基本功能之外,要具备一个扩展功能就是比较(为什么不是treeset集合掌握这个功能呢?)。这个比较怎么来呢?它本身已经被定义在congparable接口当中,如果你想让人具备比较性,只要对人进行一个功能扩展,让其实现comparable接口,就具备了比较功能。

    人需要进行比较,因此要实现comparable(在eclipse中大小写都可以,名字太长的可以采用out+斜线)

    要先继承后实现,不写继承object也行。person类中覆盖了Comparable接口中的copareTo方法。这里返回的是int,对象比较返回的是什么结果?不要说成-1,那其实是负数,数字随时可以变化的。

    现在回过来看原先的例子,输入五个元素,看下图,结果没有错误。

     输出只有一个,但是没有报错。我们将wangwu换到第一个添加位置,结果只输出wangwu。先存的是wangwu,当存储zhangsan的时候,它和wangwu一比,返回的是0,返回0意味着这两个元素相同,而treeset集合是set集合的一个子类,它们都有一个共性特点,叫做保证元素的唯一性。

    treeset和hashcode,equals有关系么?一点关系都没有,例子开始时,就有hashcode和equals两个方法,输出也是报错,也没行。

    treeset集合根本就不看hashcode和equals,而正因为写了一个compareto方法,并返回了0,它就视为下面的元素和wangwu相同。所以treeset集合判断元素唯一性的方式特别简单,就是根据.....

    因为结构不一样,和其它容器全不一样,treeset就看比较结果,只要是0,就按相同算。

    有人说,不能这么算,得写一些具体的,意思是说,上面解决异常的操作太粗糙了。没有用到对象自身的一些特性,直接compareto得到0,现在想要精细一些。

    把person存到treeset中,没有说要按照什么明确的需求排,这就是问题。

    人这个类既有姓名,又有年龄,按照什么方式排序没有明确过,这是问题。现在,我们开始明确,以person对象的年龄按照从小到大来进行排序。也就是说我们要将这个要求写在person的compareto方法里。要是返回0,那么所有元素都相同,那肯定是不行的。

    我们先要转换对象类型,有人说这里需要进行判断。这里就不用了,以后会进行统一的改观。现在先简化地写一下,判断肯定是需要地。凡是类型强转,尤其是引用数据类型之前,一定要先加健壮性判断(instanceof),否则会发生classcast异常。下面就是将person类中的compareto方法进行复写的结果。

    按照年龄比较的结果来存储数据到集合中。最终显示是可以的,这是分布在两个class文件中的代码,treeset应该还有其它的限制条件,不仅仅是目前compareto方法中的比较年龄。

    我们看输出的结果是从小到大的,如何将其调整为从大到小。将return中的-1和1调换一下。还有另一种方法,将this和p调换一下。后期有一种对顺序进行逆转的动作,源码中return中的-1和1,以及<和>都是很难改变的,但是this和p是引用变量,方法修改。

    排完序后,对程序进行修改,将其中的两个自定义对象的年龄设置成一样的。

    结果中zhouqi不在了,wangwu还在。原因是什么?在compareto方法的定义中,zhouqi和wangwu的年龄既不大于,也不小于,是等于。那么这两个元素就是一样的,是同一个对象,这样zhouqi就被取消了。

    有人说这个判断少一步,当年龄判断相同的时候,应该再判断一次姓名。

    注意,我们在写这个比较动作的时候,我们通常依据的条件都不唯一,叫做有可能有主要条件的同时,还存在着次要条件。叫做如果主要条件相同,继续按照次要的条件继续进行比较。

    有的条件不唯一,那就继续写(说的都是compareto方法体中的定义)。如果年龄排不了了,那就按照姓名排。姓名是字符串,字符串本身具备着compareto的方法,

    它的这个方法也来自与comparable接口。只要对象想要进行比较,就实现这个comparable接口(统一接口)。

    但是这两种写法不太好,换种简单的写法。

    修改完之后,wangwu和zhouqi都出现了,并且wangwu排在前面。

    上面讲述的就是treeset可以对元素进行排序的操作。为什么刚才往里面存储字符串就可以排序呢?因为字符串本身就实现了comparable。

  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/wsw-bk/p/8308398.html
Copyright © 2011-2022 走看看