TIJ阅读笔记(第十一章)(2)
2008-02-23 10:01:10来源:互联网 阅读 ()
Collections类里专门有一个会返回与对象自有的比较法相反的Comparator的方法。它能很轻易地被用到CompType上面。
Collections.reverseOrder()返回了一个Comparator的reference。
compare()方法会根据第一个参数是小于,等于还是大于第二个参数,分别返回负整数,零或是正整数。
数组的排序
有了内置的排序方法之后,你就能对任何数组排序了,不论是primitive的还是对象数组的,只要它实现了Comparable接口或有一个与之相关的Comparator对象就行了。
Java标准类库所用的排序算法已经作了优化--对primitive,它用的是“快速排序(Quicksort)”,对对象,它用的是“稳定合并排序(stable merge sort)”。所以除非是prolier表明排序算法是瓶颈,否则你不用为性能担心。
查询有序数组
一旦数组排完序,你就能用Arrays.binarySearch()进行快速查询了。但是切忌对一个尚未排序的数组使用binarySearch();因为这么做的结果是没意义的。
如果Arrays.binarySearch()找到了,它就返回一个大于或等于0的值。否则它就返回一个负值,而这个负值要表达的意思是,如果你手动维护这个数组的话,这个值应该插在哪个为止。这个值就是:
-(插入点)-1
“插入点”就是,在所有“比要找的那个值”更大值中,最小的那个值的下标,或者,如果数组中所有的值都比要找的值小,它就是a.size()。
如果数组里面有重复元素,那它不能保证会返回哪一个。这个算法不支持重复元素,不过它也不报错。所以,如果你需要的是一个无重复元素的有序序列的话,那么可以考虑使用本章后面所介绍的TreeSet(支持【排序顺序“sorted order”】)和LinkedHashSet(支持【插入顺序“sorted order”】)。这两个类会帮你照看所有细节。只有在遇到性能瓶颈的时候,你才应该用手动维护的数组来代替这两个类。
如果排序的时候用到了Comparator(针对对象数组,primitive数组不允许使用Comparator),那么binarySearch()的时候,也必须使用同一个Comparator(用这个方法的重载版)。
数组部分的总结
总而言之,如果你要持有一组对象,首选,同时也是效率最高的选择,应该是数组。而且,如果这是一组primitive的话,你也只能用数组。还有一些更为一般的情况,也就是写程序的时候还不知道要用多少对象,或者要用一种更复杂方式来存储对象情况。为此,Java提供了“容器类(container class)”。其基本类型有List,Set和Map。
它们还有一些别的特性。比方说Set所持有的对象,个个都不同,Map则是一个“关联性数组(associative array)”,它能在两个对象之间建立联系。此外,与数组不同,它们还能自动调整大小,所以你可以往里面放任意数量的对象。
容器简介
Java2的重新设计了1.0和1.1里面那个表现差劲的容器类。新的设计更紧凑也更合理。同时它也补齐了容器类库的功能,提供了链表(linked list),队列(queue)和双向队列(deques,读成“decks”)这几种数据结构的功能。
Java2的容器类要解决“怎样持有对象”,而它把这个问题分成两类:
1。Collection:通常是一组有一定规律的独立元素。List必须按照特定的顺序持有这些元素,而Set则不能保存重复的元素。(bag没有这个限制,但是Java的容器类库没有实现它,因为List已经提供这种功能了)
2。Map:一组以“键--值”(key-value)形式出现的pair。初看上去,它应该是一个pair的Collection,但是真这么去做的话,它就会变得很滑稽,所以还是把这个概念独立列出来为好。退一步说,真的要用到Map的某个自己的时候,创建一个Collection也是很方便的。Map可以返回“键(key)的”Set,值的Collection,或者pair的Set。和数组一样,Map不需要什么修改,就能很容易地扩展成多维。你只要直接把Map的值设成Map就可以了(然后它的值再是Map,依此类推)。
Java的容器类分成两种基本类型。它们的区别就在,每个位置能放多少对象。Collection只允许每个位置上放一个对象(这个名字有点误导,因为容器类库也常被统称为collections)。它包括“以一定顺序持有一组对象”的List,以及“只能允许添加不重复的对象”的Set。ArrayList是一种List,而HashSet则是一种Set。你可以用add()方法往Collection里面加对象。
Map保存的是“键(key)--值”形式的pair,很像是一个微型数据库。
Map又被称为关联性数组(associative array)。你可以用put()方法往Map里面加元素。它接受键--值形式pair作参数。
fill()方法还为Collection和Map作了重载。输出在默认情况下使用容器类的toString()方法。打印出来的Collection会用方括号括起来,元素与元素之间用逗号分开。Map会用花括号括起来,键和值之间用等号联起来(键在左边,值在右边)。
List会老老实实地持有你所输入的所有对象,既不做排序也不做编辑。Set则每个对象只接受一次,而且还要用它自己的规则对元素进行重新排序(一般情况下,你关心的只是Set包没包括某个对象,而不是它到底排在哪里--如果是那样,你最好还是用List)。而Map也不接收重复的pair,至于是不是重复,要由key来决定。此外,它也有它自己的内部排序规则,不会受输入顺序影响。如果插入顺序是很重要的,那你就只能使用LinkedHashSet或LinkedHashMap了。
填充容器
和Arrays一样,Collection也有一个叫Collections的辅助类,它包含了一些静态的实用工具方法,其中就有一个fill()。这个fill()也只是把同一个对象的reference复制到整个容器,而且它还只能为List,不能为Set和Map工作。
容器的缺点:不知道对象的类型
Java的容器有个缺点,就是往容器里面放对象的时候,会把对象的类型信息给弄丢了。这是因为开发容器类的程序员不会知道你要用它来保存什么类型的对象,而让容器仅只保存特定类型的对象又会影响它的通用性。所以容器被做成只有持有Object,也就是所有对象的根类的reference,这样它就能持有任何类型的对象了。(当然不包括primitive,因为它们不是对象,也没有继承别的对象。)这是一个很了不起的方案,只是:
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
