刘文涛

Flex3,Struts2,Hibernate3,Spring2,UML,Oracle,mysql,tomcat,compass,lucene

   :: 首页 ::  ::  ::  :: 管理 ::

2006年8月29日 #

Commons和Lang组件简介
  Jakarta Commons 项目旨在实现可重用的 Java 组件。此项目包含数十个组件,用以简化 Java 的开发,每个组件负责满足一个特定需求。有大量的组件可用,且不仅限于在特定类型的Java应用程序中使用。

项目分类在两个部件中:

Commons Proper:Commons Proper中的项目已可以投入实际使用。 
Commons Sandbox:sandbox内的项目仍然处于实验阶段。 

目前Commons Proper中有33个项目,Commons Sandbox中有22个项目,

故而,任何一类Java项目都有其存在的意义。

  Lang组件是Jakarta Commons中较为流行的组件之一。Lang是要呈现在J2SE本身中的一组类。

  在本文中,我们将了解Lang最有用的一些功能。要注意的是,也可以只使用基本Java类来完成Lang的每个功能,但相对于自己学习、理解并编写代码而言,使用Lang要简单得多。即使您能够写出最好的代码,使用经过实验和测试的Lang的功能会更快一些,能节省大量的检查与测试时间。随着Lang一起提供了特有的JUnit测试用例,Lang的使用极其广泛,已经历了其创建者和现实世界的种种考验。

  Lang的一个重要特征是其简单性。通常来说,新的Java组件十分复杂,要了解若干种技术才能使用这些组件。要理解组件的用途通常都很难,更别说实际使用该组件了。但对于大多数Commons组件而言,这就不是问题了。Lang一类组件使用方便,无论对Java初学者还是高级Java用户都非常有用。

  如果在采用技术前需要有十足的保证,则请在保存您的Java软件的目录中搜索commons-lang*.jar。结果会让您感到很意外。 Tomcat、Struts、Hibernate、Spring和WebWork 等常见Java项目都使用Lang。

  首先让我们看一看使用Lang进行大多数开发人员几乎每天必须进行的操作——字符串操作。

一 :处理字符串

  无论应用程序是基于Swing、J2EE或J2ME的,它都必须使用字符串。所以,尽管在Java中使用字符串相当简单,但是如果希望按照一定的条件修改和处理字符串,事情就不那么简单了。您不得不在各种与字符串相关的类中寻找各种不常用的方法,然后想办法使其协同工作,以获得所需的结果。虽然有些Lang方法与J2SE中的某些方法重叠,但在大多数情况下,一个Lang方法就可提供各种类中的多个J2SE方法的功能,从而帮助您获得所需的输出。
 
  Lang组件有许多专门用于字符串操作的类。现在我们将使用一个简单的Java应用程序来演示一些较为有用的类和方法。

  当应用程序接受用户输入时,由于用户可能会存在输入错误的情况,或用户可能以各种格式输入数据,而您希望只采用一种格式进行处理和存储,则通常会涉及到对字符串进行操作。
 
  例如,您有一个带输入框的窗体,用户在此输入框内输入许可证密钥。您希望允许输入1110-JAVA格式的密钥。您必须进行以下操作:

检查是否为空字符串。 
忽略空格。 
密钥区分大小写。 
用“
- ”标记分隔密钥字符串,然后检查第一部分是否全部是数字,第二部分包含的字符是否只来自有效字符集“J”、“A”、“V”、“A”。 
两个部分均应有四个字符。 
第一部分的第四个数字应该是“
0 ”。


  只有当密钥满足所有这些条件时,应用程序才会查询数据库,检查该密钥是否合法。
  如果不花大量的时间浏览String、StringTokenizer和其他类的API文档,您能完成以上的任务么?我不能,所以现在我将试着用Lang组件来管理验证。

清单1. checkLicenseKey()方法

 1 /* *
 2  * Check if the key is valid
 3  * @param key license key value
 4  * @return true if key is valid, false otherwise.
 5   */

 6 public static  boolean  checkLicenseKey(String key) {
 7      // checks if empty or null
 8      if (StringUtils.isBlank(key)) {
 9          return   false ;
10     }

11
12      // delete all white space
13     key =  StringUtils.deleteWhitespace(key);
14
15      // Split String using the - separator
16     String[] keySplit  =  StringUtils.split(key,  " - " );
17
18      // check lengths of whole and parts
19      if (keySplit.length  !=   2
20          ||  keySplit[ 0 ].length()  !=   4
21          ||  keySplit[ 1 ].length()  !=   4 {
22          return   false ;
23     }

24
25      // Check if first part is numeric
26      if ( ! StringUtils.isNumeric(keySplit[ 0 ])) {
27          return   false ;
28     }

29
30      // Check if second part contains only
31      // the four characters 'J', 'A', 'V' and 'A'
32      if ( !  StringUtils.containsOnly(keySplit[ 1 ]
33             , new   char [] {'J', 'A', 'V', 'A'} )) {
34          return   false ;
35     }

36
37      // Check if the fourth character
38     // in the first part is a '0'
39      if (StringUtils.indexOf(keySplit[ 0 ], ' 0 ')  !=   3 ) {
40          return   false ;
41     }

42
43      // If all conditions are fulfilled, key is valid.
44      return   true ;
45 }

  在清单1中,我们使用了org.apache.commons.lang.StringUtils类中提供的各种方法,根据我们先前定义的所有规则对字符串进行验证。

isBlank()方法检查字符串是否为空。
deleteWhitespace()方法确保字符串不包含空格。
然后我们使用split()方法对字符串进行分隔,
并使用isNumeric()、
containsOnly()
和indexOf()方法

对密钥的两部分进行验证。

  请注意,尽管在J2SE中已经有了indexOf()方法,最好使用StringUtils中的indexOf()。与J2SE indexOf()方法不同,使用StringUtils indexOf()时无需担心空指针的问题。触发NullPointerException被认为是Java程序员最常犯的错误。Lang可以确保您不会犯同样的错误。即使向indexOf()或其他此类方法传递一个null,都不会引发NullPointerException。indexOf()将直接返回-1。

  这样,只需几行简单代码,就可以实现相应的功能,而采用其他方法需要编写很多行代码,而且十分麻烦。如果使用清单2中所示的主方法执行checkLicenseKey()方法,所得到的结果如清单3所示。

清单2. main()方法

public static  void  main(String[] args)  {
    String []key
=   { " 1210-JVAJ " , " 1211-JVAJ " " 210-JVAJ " " 1210-ZVAJ " } ;
    
for  ( int  i = 0 ; i  <  key.length; i ++ ) {
        
if (checkLicenseKey(key[i])) {
            System.out.println(key[i]
+   "  >> Is Valid " );
        }

        
else {
            System.out.println(key[i]
+   "  >> Is InValid " );
        }

    }

}

清单3. 输出

1210 - JVAJ  >>  Is Valid
1211 - JVAJ  >>  Is InValid
210 - JVAJ  >>  Is InValid
1210 - ZVAJ  >>  Is InValid

  大部分用于进行字符串操作的方法都隶属于org.apache.commons.lang.StringUtils,但也有其他的类可以使用。

1 CharUtilsCharSetUtils分别提供使用字符字符集的实用方法。
2 WordUtils是在2.0版中首次出现的类,用于承载专门用于处理字的实用方法。
          不过,由于字符串和字的处理上有大量的重叠操作,使得此类似乎有点没有存在的必要了。
3 RandomStringUtils类可以根据各种规则生成随机字符串

 

二 :对象比较与排序

  经常需要对数据对象进行比较,并据此进行排序。那么我们如何对清单6中所给出的Computer类的对象进行比较和排序呢?

  您猜猜!让我们使用Lang根据计算机的成本对Computer对象进行排序。若要比较对象,需要实现java.lang.Comparable接口。此接口具有惟一的方法compareTo(Object)。此方法实现将当前对象和传递给此方法的对象进行比较。如果此对象小于、等于或大于指定的对象,此方法将分别返回负数、零或正数。
  为了对Computer对象进行比较,在Computer类中实现compareTo() 方法,如清单8所示。

清单8. compareTo()方法

public int compareTo(Object obj) {
    Computer anotherComputer = (Computer)obj;
    //return new CompareToBuilder().reflectionCompare(this, anotherComputer);
    return new CompareToBuilder().
   append(this.cost, anotherComputer.cost).toComparison();
}

  然后,为了实际进行比较,我们编写一个名为ComputerSor的简单类,如清单9中所示。我们只向ArrayList添加三个对象,然后进行排序。

清单9. ComputerSort类
public class ComputerSort  {

    public static void main(String[] args) {
        ArrayList computerList = new ArrayList();
        computerList.add(new Computer("Pentium","black", 1000));
        computerList.add(new Computer("Pentium","chocolate", 334));
        computerList.add(new Computer("Pentium","darkgray", 2234));

        Collections.sort(computerList);
        System.out.println(computerList);
    }

}

  执行ComputerSort时,将看到对象根据cost字段的值进行了排序。CompareToBuilder与ToStringBuilder类似,也有一个基于反射的用法选项。我们已对清单8中的compareTo()方法中的位元进行了注释,因为,在此种情况下,反射选项将比较所有字段,最终获得不正确的结果。如果既不希望比较当前类中的字段,也不希望比较其超类中的字段,CompareToBuilder也提供了可以用于此用途的方法。执行ComputerSort类的输出如清单10中所示。

清单10. 排序后的Computer对象
[dev2dev.Computer@cf2c80[processor=Pentium,color=chocolate,cost=334]
, dev2dev.Computer@12dacd1[processor=Pentium,color=black,cost=1000]
, dev2dev.Computer@1ad086a[processor=Pentium,color=darkgray,cost=2234]]

结束语
  本文中,我们了解了Jakarta Commons Lang组件的一些主要功能。总的说来,Commons项目是非常有用的项目,但并没有得到充分利用。虽然开源项目使用了许多Commons组件,但其在开源世界之外的应用并不十分广泛。现在您已经对Lang的功能有所了解,应该考虑立即将其应用到您的应用程序中。另外,还可以在Commons项目中寻找各种有用的组件,从而简化XML解析、使应用程序进行HTTP会话、实现系统化验证以及执行很多其他功能。

posted @ 2006-08-29 14:40 刘文涛| 编辑 收藏