自定义对象作为Properties的键进行中文排序的算法实现研究

2013-03-20 07:18马会成
科技视界 2013年10期
关键词:实例排序对象

马会成

(1.宁夏职业技术学院,宁夏 银川750002;2.宁夏广播电视大学,宁夏银川750002)

1 properties概述

在java.util数据包里有一个 Properties类,它是JAVA集合类中的一个保存数据的类,通常用于处理软件项目中的配置文件,Properties对象中的每一个数据保存的是一个键值对,键和值是一一对应关系,而且键必须是唯一的,否则就会发生数据覆盖,也就是说,如果键出现了重复,那么后保存的数据就会覆盖以前保存的相同键对应的数据。

Properties类能够处理数据项对应的属性,而且它具有持久性,属性的每个键和值可以是自定义对象,也可以是字符串,但更常见的是字符串,它既可以保存在流中也可以从流中加载,既可以在一个属性列表中设定它的“默认值”,也可以让另一个属性列表作为它的“默认值”,Properties类的自动同步功能和 它的setProperty方法提供的处理字符串的安全性,这些方便的功能使得在软件项目中得到了越来越多的应用。

需要注意的是,由于Properties类是从Hashtable继承而来,因而可以对Properties的对象应用Hashtable中的put和putAll方法,但是不建议使用put和putAll方法,因为它们允许调用者插入其键或值不是 String的项,这将导致软件和项目的安全性受到影响,建议使用setProperty方法。如果要使用Properties中的store、propertyNames、save、list方法,那么Properties对象中属性必须是String类型的键和值。

Properties类虽然支持中文排序,但是它的局限性在于需要开发人员自行设计算法,并手工完成一些代码,而且它没有提供对自定义对象的排序算法及其实现,将自定义对象作为Properties的键进行中文排序的算法,将会使得Properties类的方便性和实用性得到进一步的扩展。

Properties类还有一种局限,那就是它既没有提供按指定的属性对自定义对象进行排序的算法,也没有提供可以直接对自定义对象进行排序的具体实现,因而,Properties类按指定的属性对自定义对象进行排序的相关算法及其实现,将使Properties类的功能得到进一步发展和完善。

2 自定义对象作为Properties的键进行中文排序的算法实现研究

自定义对象作为Properties的键按键进行排序时,可以使用自定义对象的某个属性值作为Properties的键,也可以使用将整个自定义对象作为Properties的键,而且通常排序还有正向排序和反向排序之分,排序字符串也有中文和英文之分,现将自定义对象作为Properties的键进行中文排序的算法概述如下:

2.1 将自定义对象中用于排序的属性作为Properties的键,并对键按中文正向进行排序

如果你只关心一个自定义对象的一个属性或者值并对其使用排序,且用于排序的属性不会重复,那么可以将该属性用于Properties的键,如果属性值重复,那么后出现的属性值将覆盖前面的出现的属性值,而不用将整个自定义对象保存到Properties中,比如,有一个学生类,其中的学号不可能重复,所以学号可以做为Properties的键,并可以按学号进行排序,基本实现算法如下:

①由于是自定义对象的排序,所以首先要有一个类,这样才能生成自定义对象,比如学生类,在类中提供学号、姓名等属性。

②由于是对自定义对象的属性进行排序,所以需要先写一个类CollatorComparator,且该类要实现Comparator接口。在该类中要提供一个方法compare,用于处理自定义对象中按指定的属性进行排序。

③用自定义类生成自定义对象,并进行初始化,然后用Properties类生成一个对象defList,并用生成的对象defList通过setProperty方法将自定义对象的属性作为键和值对defList进行初始化。注意,这里排序关键字不能重复,如果重复,将覆盖前面的有相同属性的对象,除非预知此结果,否则请不要使用此种覆盖。

④用上面自己写的类CollatorComparator生成一个对象的实例comparator。

⑤用new ArrayList(defList.entrySet())生成一个实例,并保存到List类的对象list1中。

⑥用 Collections.sort(list1,comparator);实现对对象 list1按comparator的规则进行排序。

⑦用List类的对象list1调用iterator(),并保存到Iterator类的对象i中。

⑧然后用一个循环处理Properties的键和值,这里要注意键和值的对应关系,可以使用i.next()得到下一个键,并转换成Map.Entry的类的对象,同时保存到Map.Entry的对象me中,这样me.getKey()保存的就是Properties的当前正在处理的键,而me.getValue()就是对应键的值。

上面在Properties中保存的都是对象的部分值,这样是为了方便按键的排序,如果想在Properties中保存完整的对象,那么就可以按对象的任何一个属性进行排序。

2.2 将整个自定义对象作为Properties的键,并对键按指定的属性进行中文正向排序

将自定义对象中用于排序的属性作为Properties的键,往往存在着属性值的重复问题,为了解决这个问题,可以将整个自定义对象作为Properties的键,这样只要自定义对象不同,不管他们用于排序的属性值是否相同,都可以将自定义对象作为Properties的键,并可以按需要的属性进行排序,但是需要注意的是,如果自定义对象相同,那么后出现的对象将覆盖前面出现过的对象。这种方案比较器两个参数的类型常有两种:Object和Map.Entry型,这里先看Object型。

●比较器两个参数的类型使用Object型,基本实现算法如下:

①由于是自定义对象的排序,所以首先要有一个类,这样才能生成自定义对象,比如Person类,在类中提供年龄、姓名等属性。

②由于是将整个自定义对象作为Properties的键,而且只是对自定义对象的属性进行排序,所以需要先写一个类CollatorComparator,且该类要实现Comparator接口。在该类中要提供一个方法compare,用于处理自定义对象中按指定的属性进行排序,该类的主要代码如下:

Collator collator=(RuleBasedCollator)java.text.Collator.getInstance (java.util.Locale.CHINA);

注意,上面的代码由于用了toString(),所以什么类型都可以比较如int型。使用此法时,如果不区分大小写,只需要在这两个toString()后加上.toLowerCase(),或者用.toUpperCase()。如果要反向排序,只需要在key1前加负号。

③用自定义类生成自定义对象,并进行初始化,然后用Properties类生成一个对象defList,并用生成的对象defList通过put方法将自定义对象的属性作为键和值对defList进行初始化。注意,这里排序关键字的值可以重复,而且只要自定义对象不重复,即使排序属性值重复也不存在导致覆盖的问题。

④用上面自己写的类 CollatorComparator一个对象的实例comparator。

⑤用Properties类生成的对象defList调用keySet()中的toArray()方法,并保存到Object型的数组key中。

⑥用Arrays.sort(key,comparator)对数组key按comparator规则进行排序。

⑦然后用一个循环处理Properties的键和值,这里要注意键和值的对应关系,(Person)key[i]保存的就是Properties的当前正在处理的键,而defList.get(key[i])就是对应键的值。

上面的方法在比较器的参数是两个Object直接转换成Person对象,这就要求比较时将比较器用于装有Person对象的容器,这只是方法中的一种.

当然我们也可以将比较器的两个参数的Object转换成Properties操作需要的Map.Entry型,这就要求比较时将比较器用于装有键值的Properties对象,然后对person类的属性name进行排序(包括中英文)。

●比较器两个参数的类型使用Map.Entry型,基本实现算法如下:

①由于是自定义对象的排序,所以首先要有一个类,这样才能生成自定义对象,比如Person类,在类中提供年龄、姓名等属性。

②由于是将整个自定义对象作为Properties的键,而且只是对自定义对象的属性进行排序,所以需要先写一个类CollatorComparator,且该类要实现Comparator接口。在该类中要提供一个方法compare,用于处理自定义对象中按指定的属性进行排序,该类的主要代码如下:

Collator collator=(RuleBasedCollator)java.text.Collator.getInstance (java.util.Locale.CHINA);

注意,上面的代码由于用了toString(),所以什么类型都可以比较如int型。使用此法时,如果不区分大小写,只需要在这两个toString()后加上.toLowerCase(),或者用.toUpperCase()。如果要反向排序,只需要在key1前加负号。

③用自定义类生成自定义对象,并进行初始化,然后用Properties类生成一个对象defList,并用生成的对象defList通过put方法将自定义对象的属性作为键和值对defList进行初始化。注意,这里排序关键字的值可以重复,而且只要自定义对象不重复,即使排序属性值重复也不存在导致覆盖的问题。

④用上面自己写的类 CollatorComparator一个对象的实例comparator。

⑤用new ArrayList(defList.entrySet())生成一个实例,并保存到List类的对象list1中。

⑥用 Collections.sort(list1,comparator);;实现对对象 list1按comparator的规则进行排序。

⑦用List类的对象list1调用iterator(),并保存到Iterator类的对象i中。

⑧然后用一个循环处理Properties的键和值,这里要注意键和值的对应关系,可以使用i.next()得到下一个键,并转换成Map.Entry的类的对象,同时保存到Map.Entry的对象me中,这样(Person)me.getKey()保存的就是Properties的当前正在处理的键即整个自定义对象,而me. getValue()就是对应键的值。

在实际使用中,将自定义对象作为Properties的值的情况更为常见,因为自定义对象作为Properties的键时,如果自定义对象相同,会有覆盖的情况,而做为值就不会出现覆盖的情况,而且用值时对其中的相关属性排序时控制更方便。

[1][美]Robert Lafore.Java数据结构和算法[M].

[2]sun公司官方网站.JDK帮助文档[OL].

猜你喜欢
实例排序对象
神秘来电
排序不等式
恐怖排序
基于熵的快速扫描法的FNEA初始对象的生成方法
区间对象族的可镇定性分析
完形填空Ⅱ
完形填空Ⅰ