分享
 
 
 

探索J2ME:对记录进行排序

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

欢迎回到《探索J2ME》——介绍用J2ME和MIDP开发应用程序的系列文章。通过对前几篇文章的学习,你应该已经了解到了J2ME的记录治理系统(RMS)为动应用程序提供了持久存储的功能。你还应该了解MIDP如何用平面文件的形式来实现存储。假如你对此并不很清楚,我建议你看看《探索J2ME》的前几篇文章,文章标题在下面列出。

假如你刚刚加入我们的行列,你可能希望查看我们早先的几篇文章:

探索J2ME:构建开销追踪系统

探索J2ME:创建开销细节表单

探索J2ME世界:使用记录治理系统

上次,我们通过RecordStore类完成了EXPensesApp应用程序的开销项目的存储功能。RecordStore类提供了对J2ME记录库的基本的访问功能。然而,lsMain显示的开销项目按照输入顺序排列产生了一个小问题,即查询某一个项目比较麻烦。

在本文中,我将介绍RMS的记录排序API——非凡是RecordEnumeration类和 RecordComparator接口,你可以在Javax.microedition.rms软件包中找到这两者。我同时还要顺便谈谈RecordFilter接口,它可以让你在记录库中查找某个非凡的记录。你可以在这儿下载最新版本ExpensesApp的代码。

用RecordComparator排序

在代码清单 A中,你会发现ExpenseInfo.LoadExpenses又一次被修改了,这次利用RecordEnumeration对象来按照记录所保存的某项数据,而不是记录插入的顺序,来从记录库中查找记录:

RecordEnumeration enu = rs.enumarateRecords(null, new ExpenseComparator, false);

RecordStore.enumerateRecords接受一个ExpenseComparator类的对象(为参数),ExpenseComparator类实现了RecordComparator的接口,RecordEnumeration用它来确定用来排序的记录的顺序。我在清单B中给出了ExpenseComparator的代码。

让我们来检测一下RecordComparator.compare方法。Compare方法用于处理两个记录,这两个记录均处于字节数组的形式(参数为bytes和bytes1数组),并且必须可以从中提取出任何可以决定先后次序的数据(决定先后次序的方式由RecordEnumeration确定)。该方法然后这样指出这两个记录的相对关系::

假如由bytes代表的记录(插入时间)在前,那么compare会返回ExpenseComparator.PRECEDES,并且bytes在bytes1之前出现在枚举(enumeration)中。

假如bytes所代表的记录(的插入时间)在 bytes1所代表的记录之后,那么compare返回ExpenseComparator.FOLLOWS,这样,byteIs在bytes之前出现在枚举中。

假如这两个记录是等价的(equivalent)(即同一天输入的),compare返回ExpenseComparator.EQUIVALENT,这两个记录的顺序任意。

在ExpenseComparator中,我从这两个记录中获取ExpenseDate字段(它以“当前时刻的毫秒数”的格式被存到记录库中)并根据这两个记录的排序返回相应的值。

实现RecordComparator时,要记住对记录库中的每一个记录至少要调用一次compare方法,(当枚举开始产生时)。所以,你需要正确引导比较过程,使得这所费时间尽量的短,以免没有必要地降低应用程序的运行速度。还有一点就是,你用于比较的两个记录在最后无需紧联(immediately adjacent),分类枚举。

使用记录枚举

你也许还记得我在上一篇文章中抱怨使用RecordStore类是如何让人感到沮丧、而它“名不副实”(相对于RMS API中的其它类)的方法又有多少。再次强调,获得MIDP类API的JavaDoc文档将会对你的J2ME工作非凡有用。

再次看看清单A中的代码,你会注重到现在记录提取循环(*译者注:用于提取、读取记录的循环*)是用RecordEnumeration.hasNextElement方法做为控制变量的。在以前,每一个开销项目的ID号保存在ExpenseInfo的一个实例中,记录中的数据——开销日期、说明、美元数、美分数(*译者注:在前面已经说过,J2ME的变量没有浮点型,所以花费用美元和美分这两个整数来表示。*)、归类——是通过两个流读取类来按顺序提取的。

联合使用RecordEnumeration和xpenseComparator使得lsMain中的开销项目按项目中的数据的顺序来显示,这就比按照开销项目插入的顺序显得更加符合逻辑。然而,即使你并没有打算对记录进行排序,你也应该考虑用RecordEnumeration来在记录库中查询记录。这样做比使用RecordStore类更加简单,而且还回避了使用RecordStore类的几个潜在问题,如我在上一篇文章结尾所提到的删除bug。

棘手的记录指针

当你留心这些不一致的方法名称时,它们就仅仅是一件令人讨厌的事而已;但是除此之外,还存在一个更大的、会令你寝食难安的问题。当你偶然粗略浏览文档后,你可能会想到,仅有nextRecord方法和previousRecord方法可以在枚举下移动记录指针。进一步思考后,你会发现并情况不是这样的,另一个方法也可以操作记录指针,这就是nextRecordId。

你必须清楚这个事实,因为当你希望更新一个记录之前,获知它的ID号几乎是不可避免的。这样,下面的查询记录的方法或许会派上用场:

调用 nextRecordId来获取枚举中下一条记录的ID号。

用nextRecord方法得到下一条记录。

获取该记录中的数据。

重复上述过程,直到最后一条记录。

上述方法的问题是:由于调用nextRecordId也会移动记录指针,当你刚刚查询完一半记录是,你就捕捉到一个莫名其妙的InvalidRecordIdException例外而不得不重新开始(to boot)。

正如你在代码清单A中所见,解决第一个问题的方法是用RecordStore.getRecord来取代RecordEnumeration.nextRecord检索记录。我知道,这个方法并不完善;但是至少可以工作。那个让人摸不着头脑的例外是在记录指针指到枚举的最后一个记录的情况下调用nextRecordId而产生,所以你在写代码时要注重避免这种情况。

用RecordFilter来查找记录

尽管我没有在ExpensesApp应用程序中完成它,RecordEnumeration也可能完成搜寻记录的功能。为了做到这一点,你要向RecordStore.enumerateRecords传递一个类(该类实现了RecordFilter的接口)的实例,并完全忽略RecordComparator。RecordFilter仅有一个名为matches方法,它接受一个字节数组参数(字节数组代表了某个记录)。该方法用于检测记录,并根据被检测的记录是否符合预定标准而返回“真”或者“假”。

举例来说,假设我们有一个RecordFilter的实现:ExpenseFilter,它在整个记录库中搜寻开销记录中的“开销分类(category)”字段符合ExpenseInfo.CATEGORYMEALS的开销项目,如代码清单C所示。为了获得只有符合上述条件的记录集合(enumeration,枚举),我可以这样组织代码:

RecordStore rs = RecordStore.openRecordStore(RS_NAME);

RecordEnumeration enu = es.enumerateRecords(new ExpenseFilter, null, false);

在这里,变量enu仅包含分类为“膳食”(这在用户界面指点)的开销记录。

工作尚未完成,我们仍需努力

到目前为止,ExpensesApp已经相当完善了。现在,它已经有了个像样的用户界面(包括添加新的开销记录的快捷方式),也有了些实际用处——在运行过程中存储信息。但是仍有一些问题:

新添加的开销记录并没有按照排序插入链表中的对应位置。

ExpenseInfo的实例中的任何改变仅仅更新内存,而没有考虑到假如该实例已经存盘,还需要将更新后的内容重新存盘——我担心这一点可能还没有人看出来。

本应用程序还不适合在移动设备运行,因为当它暂停运行时,它没有试图释放它所占用的资源——而这一点是移动设备应用程序所必须考虑的。

在下一篇文章中,我将向你介绍如何用“活的” RecordEnumeration和记录改变通知API来解决上述缺陷。

本文相关连接请点这里

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有