




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、为了解决对象数组长度不可改变,需要向数组中增加数据需要考虑对象数组的容量等问题,在这里引入java 类的集合的概念特点: 此类的集合大小不确定,大小可变。java.util.* 包 其中有:l collection元素的类的集合 list元素的序列,可以重复 set没有重复元素的类的集合?sortedset没有重复元素的而且已经排序的类的集合 treeset有序的存放,依靠compareable接口 hashset散列的无序的存放l map二元偶对的集合,key value, 不能重复 主要功能作为查找使用,不是输出 sortedmap二元偶对的集合,已经排序而且不能重复l iterator一
2、个可以遍历整个类的集合的对象,可获得或删除元素 listiterator可以遍历一个list的对象,允许双向遍历列表,并可以修改单元n 其中,list 是接口,我们需要依靠子类arraylist来进行实例化。araylist类扩展了abstractlist 并且执行list接口是个动态数组(异步处理方式)使用格式为: list list= new arraylist() 子类对象为父接口实例化1. 方法:add(object obj)存储方法xxx,xxx,xxx,xxx 加入数据的顺序和存储顺序相同2. 方法:add(int index, object obj)index从0开始计数,加入特
3、定位置加入时最好加入同一种对象。3. 方法:remove(int index)删除特定位置的元素4. 方法:size()求出对象的总数5. 方法:get(int index)获得特定位置的元素n 使用iterator 输出元素iterator iter = erator()1. 方法:hasnext()判断是不是有内容可以继续迭代2. 方法:next()返回下一个元素while(iter.hasnext()object obj = iter.next();system.out.println(obj);n 限制加入元素的类型list list = new arraylist()
4、n linkedlist类 基本数据结构为:数据+上一个元素的地址+下一个元素的地址n hashset类hashset类扩展了abstractset并且实现了set 接口使用散列表存储数据。无序列存储,不是加入的顺序,元素不可以重复,重复的元素只保留一个, 其他方面的和list 一致.set set = new hashset()n hashmap类使用散列表实现map接口,是map接口的接口子类,以map为标准进行操作是一种映射类 key value (电话本:姓名和电话的关系)map map = new hashmap()1. 方法:put(object ket, object value
5、)加入元素2. 方法:get(object key)根据key取出内容.没有key 则返回nullmap 接口的对象不能用iterator 输出,因为它存储的是二元偶对,如果需要,必须使用以下步骤map set iterator mapentry key、valueset set = map.entryset();iterator iter = set.iterator();while(iter.hasnext()map.entry me = (map.entry) iter.next();me.getkey();me .getvalue();n treemap类map map = new t
6、reemap()会按照键值进行排序n hashtable类map map = new hashtable()和hashmap类似(同步),但hashtable是同步的没有太多的区别采用映射的方式 key value不支持迭代函数n properties 类是hashtable的子类,与tashtable 不同的是这个类主要是保存字符串的1. 方法:setproperties(string key, string value)2. 方法:getproperties(string key)3. 方法:getproperties(string key, string defaultvalue )/t
7、odo: compareable=hashtable和hashmap的比较2007年09月25日 星期二 下午 05:42hashtables提供了一个很有用的方法可以使应用程序的性能达到最佳。 hashtables(哈希表)在计算机领域中已不是一个新概念了。它们是用来加快计算机的处理速度的,用当今的标准来处理,速度非常慢,而它们可以让你在查询许多数据条目时,很快地找到一个特殊的条目。尽管现代的机器速度已快了几千倍,但是为了得到应用程序的最佳性能,hashtables仍然是个很有用的方法。设想一下,你有一个包含约一千条记录的数据文件?比如一个小企业的客户记录?还有一个程序,它把记录读到内存中进
8、行处理。每个记录包含一个唯一的五位数的客户id号、客户名字、地址、帐户结余等等。假设记录不是按客户id号顺序分类的,所以,如果程序要将客户号作为“key” 来查找一个特殊的客户记录,唯一的查找方法就是连续地搜索每个记录。有时侯,它会很快找到你需要的记录;但有时侯,在程序找到你需要的记录前,它几乎已搜索到了最后一条记录。如果要在1,000条记录中搜索,那么查找任何一条记录都需要程序平均查核500.5 (1000 + 1 )/2)条记录。如果你常需要查找数据,你应该需要一个更快的方法来找到一条记录。一种加快搜索的方法就是把记录分成几段,这样,你就不用搜索一个很大的列表了,而是搜索几个短的列表。对于
9、我们数字式的客户id号,你可以建10个列表?以0开头的id号组成一个列表,以1开头的id号组成一个列表,依此类推。那么要查找客户id号38016,你只需要搜索以3开头的列表就行了。如果有1,000条记录,每个列表的平均长度为100(1,000条记录被分成10个列表),那么搜索一条记录的平均比较次数就降到了约50。当然,如果约十分之一的客户号是以0开头的,另外十分之一是以1开头的,等等,那么这种方法会很适合。如果90%的客户号以0开头,那么那个列表就会有900条记录,每次查找平均需要进行450次比较。另外,程序需要执行的搜索有90%都是针对以0开头的号码的。因此,平均比较数就大大超过简单数学运算
10、的范围了。如果我们可以按这样一种方式在我们的列表中分配记录,情况就会好一些,即每个列表约有相同条目的记录,而不管键值中数字的分布。我们需要一种方法能够把客户号码混合到一起并更好地分布结果。例如,我们可以取号码中的每位数,乘以某个大的数(随着数字位置的不同而不同), 然后将结果相加产生一个总数,把这个数除以10,并将余数作为索引值(index)。当读入记录时,程序在客户号码上运行这个哈希(hash) 函数来确定记录属于哪个列表。当用户需要查询时,将同一个哈希函数作为一个“key”用于客户号码,这样就可以搜索正确的列表了。 像这样的一个数据结构就称为一个哈希表(hashtable)。java中的h
11、ashtablesjava包含两个类,java.util.hashtable 和java.util.hashmap,它们提供了一个多种用途的hashtable机制。这两个类很相似,通常提供相同的公有接口。但它们的确有一些重要的不同点,我在后面会讲到。hashtable和hashmap对象可以让你把一个key和一个value结合起来,并用put() 方法把这对key/value输入到表中。然后你可以通过调用get()方法,把key作为参数来得到这个value(值)。只要满足两个基本的要求,key和value可以是任何对象。注意,因为key和value必须是对象,所以原始类型(primitive
12、types)必须通过运用诸如integer(int)的方法转换成对象。为了将一个特定类的对象用做一个key,这个类必须提供两个方法,equals() 和 hashcode()。这两个方法在java.lang.object中,所以所有的类都可以继承这两个方法;但是,这两个方法在object类中的实现一般没什么用,所以你通常需要自己重载这两个方法。equals()方法把它的对象同另一个对象进行比较,如果这两个对象代表相同的信息,则返回true。该方法也查看并确保这两个对象属于相同的类。如果两个参照对象是完全一样的对象,object.equals()返回true,这就说明了为什么这个方法通常不是很适
13、合的原因。在大多数情况下,你需要一个方法来一个字段一个字段地进行比较,所以我们认为代表相同数据的不同对象是相等的。hashcode()方法通过运用对象的内容执行一个哈希函数来生成一个int值。hashtable和hashmap用这个值来算出一对key/value位于哪个bucket(哈希元)(或列表)中。作为例子,我们可以查看一下string 类,因为它有自己的方法来实现这两个方法。string.equals()对两个string对象一个字符一个字符地进行比较,如果字符串是相同的,则返回true:string myname = einstein;/ the following test is
14、/ always trueif ( myname.equals(einstein) ) .string.hashcode()在一个字符串上运行哈希函数。字符串中每个字符的数字代码都乘以31,结果取决于字符串中字符的位置。然后将这些计算的结果相加,得到一个总数。这个过程似乎很复杂,但是它确保能够更好地分布值。它也证明了你在开发你自己的hashcode()方法时,能够走多远,确信结果是唯一的。例如,假设我要用一个hashtable来实现一个书的目录,把书的isbn号码作为搜索键来进行搜索。我可以用string类来承载细节,并准备好了equals()和hashcode()方法。我们可以用put()方
15、法添加成对的key/value到hashtable中。put()方法接受两个参数,它们都属于object类型。第一个参数是key;第二个参数是value。put()方法调用key的hashcode()方法,用表中的列表数来除这个结果。把余数作为索引值来确定该条记录添加到哪个列表中。注意,key在表中是唯一的;如果你用一个已经存在的key来调用put(),匹配的条目就被修改了,因此它参照的是一个新的值,而旧的值被返回了(当key在表中不存在时,put()返回空值)。要读取表中的一个值,我们把搜索键用于get()方法。它返回一个转换到正确类型的object参照:bookrecord br =(bo
16、okrecord)isbntable.get(0-345-40946-9);system.out.println(author: + br.author+ title: + br.title);另一个有用的方法是remove(),其用法同get()几乎一样,它把条目从表中删除,并返回给调用程序。你自己的类如果你想把一个原始类型用做一个key,你必须创建一个同等类型的对象。例如,如果你想用一个整数key,你应该用构造器integer(int)从整数中生成一个对象。所有的封装类?如integer、float和boolean?都把原始值看做是对象,它们重载了equals()和hashcode()方法
17、,因此,它们可以被用做key。jdk中提供的许多其它的类也是这样的(甚至hashtable和hashmap类都实现它们自己的equals()和hashcode()方法),但你把任何类的对象用做hashtable keys前,应该查看文件。查看类的来源,看看equals()和hashcode()是如何实现的,也很有必要。例如,byte、character、short和integer都返回所代表的整数值作为哈希码。这可能适合,也可能不适合你的需求。在java中运用hashtables(续)如果你想创建一个hashtable,这个hashtable运用你自己定义的一个类的对象作为key,那么你应该确
18、信这个类的equals()和hashcode()方法提供有用的值。首先查看你扩展的类,确定它的实现是否满足你的需求。如果没有,你应该重载方法。任何equals()方法的基本设计约束是,如果传递给它的对象属于同一个类,而且它的数据字段设定为表示同样数据的值,那么它就应该返回true。你也应该确信,如果传递一个空的参数给该方法,那么你的代码返回false:public boolean equals(object o)if ( (o = null)| !(o instanceof myclass)return false;/ now compare data fields.另外,在设计一个hashc
19、ode()方法时,应该记住一些规则。首先,该方法必须为一个特定的对象返回相同的值,而不管这个方法被调用了多少次(当然,只要对象的内容在调用之间没有改变,在将一个对象用做一个hashtable的key时,应该避免这一点)。第二,如果由你的equals()方法定义的两个对象是相等的,那么它们也必须生成相同的哈希码。第三,这更像是一个方针,而不是一个原则,你应该设法设计方法,使它为不同的对象内容生成不同的结果。如果偶尔不同的对象正好生成了相同的哈希码,这也不要紧。但是,如果该方法只能返回范围在1到10的值,那么只能用10个列表,而不管在hashtable中有多少个列表。在设计equals()和has
20、hcode()时,另一个要记住的因素是性能问题。每次调用put()或get(),都包括调用hashcode()来查找正确的列表,当get()扫描列表来查找key时,它为列表中的每个元素调用equals()。实现这些方法使它们尽可能快而有效地运行,尤其当你打算使你的类公开可用时,因为其它的用户可能想在执行速度很重要的情况下,在高性能的应用程序中运用你的类。hashtable性能影响hashtable功效的主要因素就是表中列表的平均长度,因为平均搜索时间与这个平均长度直接相关。很显然,要减小平均长度,你必须增加hashtable中列表的数量;如果列表数量非常大,以至于大多数列表或所有列表只包含一条
21、记录,你就会获得最佳的搜索效率。然而,这样做可能太过分了。如果你的hashtable的列表数远远多于数据条目,那你就没有必要做这样的内存花费了,而在一些情况下,人们也不可能接受这样的做法。在我们前面的例子中,我们预先知道我们有多少条记录?1,000。知道这点后,我们就可以决定我们的hashtable应该包含多少个列表,以便达成搜索速度和内存使用效率之间最好的折衷方式。然而,在许多情况下,你预先不知道你要处理多少条记录;数据被读取的文件可能会不断扩大,或者记录的数量可能一天一天地发生很大的变化。随着条目的增加,hashtable和hashmap类通过动态地扩展表来处理这个问题。这两个类都有接受表
22、中列表最初数量的构造器,和一个作为参数的负载系数(load factor):public hashtable(int initialcapacity,float loadfactor)public hashmap(int initialcapacity,float loadfactor)将这两个数相乘计算出一个临界值。每次给哈希表添加一个新的条目时,计数就被更新,当计数超过临界值时,表被重新设置(rehash)。(列表数量增加到以前数量的两倍加1,所有的条目转移到正确的列表中。)缺省的构造器设定最初的容量为11,负载系数是0.75,所以临界值是8。当第九条记录被添加到表中时,就重新调整哈希表,
23、使其有23个列表,新的临界值将是17(23*0.75的整数部分)。你可以看到,负载系数是哈希表中平均列表数量的上限,这就意味着,在缺省情况下,哈希表很少会有许多包含不只一条记录的列表。比较我们最初的例子,在那个例子中,我们有1,000条记录,分布在10个列表中。如果我们用缺省值,这个表将会扩展到含有1,500多个列表。但你可以控制这点。如果用负载系数相乘的列表数量大于你处理的条目数,那么表永远不会重制,所以我们可以仿效下面的例子:/ table will not rehash until it/ has 1,100 entries (10*110):hashtable myhashtable
24、= new hashtable(10, 110.0f);你可能不想这么做,除非你没有为空的列表节省内存,而且不介意额外的搜索时间,这可能在嵌入系统中会出现这种情况。然而,这种方法可能很有用,因为重新设置很占用计算时间,而这种方法可以保证永远不会发生重新设置这种情况。注意,虽然调用put()可以使表增大(列表数量增加),调用remove()不会有相反的结果。所以,如果你有一个大的表,而且从中删除了大部分条目,结果你会有一个大的但是大部分是空的表。hashtable和hashmaphashtable和hashmap类有三个重要的不同之处。第一个不同主要是历史原因。hashtable是基于陈旧的di
25、ctionary类的,hashmap是java 1.2引进的map接口的一个实现。也许最重要的不同是hashtable的方法是同步的,而hashmap的方法不是。这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多线程的应用程序中用一个hashtable,但你必须同样地为一个hashmap提供外同步。一个方便的方法就是利用collections类的静态的synchronizedmap()方法,它创建一个线程安全的map对象,并把它作为一个封装的对象来返回。这个对象的方法可以让你同步访问潜在的hashmap。这么做的结果就是当你不需要同步时,你不能切断hashtable中的同步(比如在一个单线程的应用程序中),而且同步增加了很多处理费用。第三点不同是,只有hashmap可以让你将空值作为一个表的条目的key或value。ha
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论