作为企业Java开发人员,我们总是需要实现各种功能,如解析XML、使用HTTP、验证输入以及处理日期等。使用Jakarta Commons项目的目的在于创建负责处理所有此类常用任务的组件,从而节约时间,让您集中精力处理核心业务解决方案。在本文中,我们将对Jakarta Commons 项目作简单介绍,然后演示如何使用Jakarta Commons内的Lang组件来处理和简化日常Java任务,比如字符串操作、使用日期和日历、比较数据对象以及对象排序等。对于本文中的所有例子,我们都将使用最新的Lang版本(即2.1版本)。
编者按:本文中的代码是根据Commons Lang的 RC1版本 编写的。其最终版不久将发行。
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应用程序来演示一些较为有用的类和方法。
当应用程序接受用户输入时,由于用户可能会存在输入错误的情况,或用户可能以各种格式输入数据,而您希望只采用一种格式进行处理和存储,则通常会涉及到对字符串进行操作。
例如,您有一个带输入框的窗体,用户在此输入框内输入许可证密钥。您希望允许输入1111-JAVA格式的密钥。您必须进行以下操作:
检查是否为空字符串。
忽略空格。
密钥区分大小写。
用“-”标记分隔密钥字符串,然后检查第一部分是否全部是数字,第二部分包含的字符是否只来自有效字符集“J”、“A”、“V”、“A”。
两个部分均应有四个字符。
第一部分的第四个数字应该是“0”。
只有当密钥满足所有这些条件时,应用程序才会查询数据库,检查该密钥是否合法。
如果不花大量的时间浏览String、StringTokenizer和其他类的API文档,您能完成以上的任务么?我不能,所以现在我将试着用Lang组件来管理验证。
清单1. checkLicenseKey()方法
/** *//**
* Check if the key is valid
* @param key license key value
* @return true if key is valid, false otherwise.
*/
public static boolean checkLicenseKey(String key)...{
//checks if empty or null
if(StringUtils.isBlank(key))...{
return false;
}
//delete all white space
key= StringUtils.deleteWhitespace(key);
//Split String using the - separator
String[] keySplit = StringUtils.split(key, "-");
//check lengths of whole and parts
if(keySplit.length != 2
|| keySplit[0].length() != 4
|| keySplit[1].length() != 4) ...{
return false;
}
//Check if first part is numeric
if(!StringUtils.isNumeric(keySplit[0]))...{
return false;
}
//Check if second part contains only
//the four characters 'J', 'A', 'V' and 'A'
if(! StringUtils.containsOnly(keySplit[1]
,new char[]...{'J', 'A', 'V', 'A'}))...{
return false;
}
//Check if the fourth character
//in the first part is a '0'
if(StringUtils.indexOf(keySplit[0], '0') != 3)...{
return false;
}
//If all conditions are fulfilled, key is valid.
return true;
}
在清单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,但也有其他的类可以使用。CharUtils和CharSetUtils分别提供使用字符和字符集的实用方法。WordUtils是在2.0版中首次出现的类,用于承载专门用于处理字的实用方法。不过,由于字符串和字的处理上有大量的重叠操作,使得此类似乎有点没有存在的必要了。RandomStringUtils类可以根据各种规则生成随机字符串。
现在,让我们了解一下Lang的另一个有用的方面:处理日期和时间的能力。
时间技术
在Java中处理日期和时间是一件相当棘手的事。如果要使用java.text.SimpleDateFormat、java.util.Calendar、java.util.Date等类,需要一定时间来适应,还需要对每一个涉及到的类和接口非常了解,才能顺利地处理日期和时间。
Lang组件彻底地简化了日期的处理,并可对其进行格式化。您可以轻松地格式化日期以进行显示、比较日期、舍入或截断日期,甚至能获取特定范围内的所有日期。
清单4. 处理日期和时间
public static void main(String[] args)
throws InterruptedException, ParseException ...{
//date1 created
Date date1= new Date();
//Print the date and time at this instant
System.out.println("The time right now is >>"+date1);
//Thread sleep for 1000 ms
Thread.currentThread().sleep(DateUtils.MILLIS_IN_SECOND);
//date2 created.
Date date2= new Date();
//Check if date1 and date2 have the same day
System.out.println("Is Same Day >> "
+ DateUtils.isSameDay(date1, date2));
//Check if date1 and date2 have the same instance
System.out.println("Is Same Instant >> "
+DateUtils.isSameInstant(date1, date2));
//Round the hour
System.out.println("Date after rounding >>"
+DateUtils.round(date1, Calendar.HOUR));
//Truncate the hour
System.out.println("Date after truncation >>"
+DateUtils.truncate(date1, Calendar.HOUR));
//Three dates in three different formats
String [] dates=...{"2005.03.24 11:03:26", "2005-03-24 11:03",
"2005/03/24"};
//Iterate over dates and parse strings to java.util.Date objects
for(int i=0; i < dates.length; i++)...{
Date parsedDate= DateUtils.parseDate(dates[i],
new String []...{"yyyy/MM/dd", "yyyy.MM.dd HH:mm:ss",
"yyyy-MM-dd HH:mm"});
System.out.println("Parsed Date is >>"+parsedDate);
}
//Display date in HH:mm:ss format
System.out.println("Now >>"
+DateFormatUtils.ISO_TIME_NO_T_FORMAT.format
(System.currentTimeMillis()));
}
清单4演示了org.apache.commons.lang.DateUtils和org.apache.commons.lang.DateFormatStringUtils类的部分功能。还有其他许多方法可以进行同样的操作,但输入格式不同。故而,如果万一您必须分析和格式化一个日期值,只需要借助提供的方法之一,利用一行代码就可以实现了。
执行清单4中代码后的输入如清单5所示。
清单5. 输出
The time right now is >>Sat Apr 09 14:40:41 GMT+05:30 2005
Is Same Day >> true
Is Same Instant >> false
Date after rounding >>Sat Apr 09 15:00:00 GMT+05:30 2005
Date after truncation >>Sat Apr 09 14:00:00 GMT+05:30 2005
Parsed Date is >>Thu Mar 24 11:03:26 GMT+05:30 2005
Parsed Date is >>Thu Mar 24 11:03:00 GMT+05:30 2005
Parsed Date is >>Thu Mar 24 00:00:00 GMT+05:30 2005
Now >>14:40:43
在清单4中,我们创建了两个日期,这两个日期仅有一秒的差别。然后使用isSameInstant()和isSameDay()方法检查这两个日期是否相同。接下来将日期进行舍入和截断,然后使用在数组中指定的各种格式对特殊日期用例进行解析。
将您的应用程序集成到第三方应用程序时,经常不能完全确定输入的格式。我曾经做过一个对旧版应用程序的集成,对于每个问题,该应用程序似乎总是有三个答案。所以,如果必须对此类应用程序提供的日期进行解析,您需要提供三个和四个不同的日期格式。清单4中使用parseDate()方法就是为了完成这项任务。这样,即使输入有变化,仍然能更对日期进行解析。还要注意,数组内模式的顺序与输入的顺序并不相同,但该方法仍然找到了适当的模式,并据此进行解析。
最后,我们按照ISO_TIME_NO_T_FORMAT格式(HH:mm:ss)对日期进行格式化并打印输入。现在我们将了解使用Lang生成常用方法toString()。
生成toString()方法
经常要用到equals()、toString()和hashCode()方法。不过,谈到实际编写这些方法的实现时,不仅我们大多数人不愿意这样做,而且我们也不能确定如何准确简单地编写这些方法。生成器程序包提供了一些实用类,可以帮助您方便地创建这些方法的实现。大多数情况下,只需要一行代码即可。下面我们将了解Lang的toString功能。
toString()方法
您可能没有注意到,在清单4中,即使我们向System.out.println()传递一个java.util.Date对象,所获得的输出仍然是正确的日期和时间显示。传递对象引用时,将自动调用toString()方法,所以可以实现这一点。那么,在我们的示例中实际上调用了java.util.Date类的toString()方法,我们能够得到正确的输出是因为有人重写了java.util.Date类中的java.lang.Object类的toString()方法。
如果没有重写toString()方法,则获得的输出只是类名称和hashcode的名称。将不会显示类中的任何数据。所以,如果编写了一个新类,且希望能得到正确的打印输出,则需要重写该类中的toString()方法。
清单6. toString()方法
相关推荐
Jakarta Commons是Apache软件基金会的一个项目集合,它包含了一系列实用工具类,用于简化Java开发工作。其中,Lang组件是Jakarta Commons中的一个核心模块,它提供了大量的静态方法,用于处理基本Java对象,如字符串...
这本书旨在帮助开发者更好地理解和利用Jakarta Commons库中的各种工具类和模块,提升Java应用程序的效率和质量。Jakarta Commons是Apache软件基金会的一个项目,它包含了一系列小型且独立的组件,这些组件提供了许多...
**Jakarta Commons API** 是一个Java开发人员广泛使用的开源库集合,它包含了多个模块,每个模块专注于特定的编程任务,从而简化了Java应用程序的开发。Jakarta Commons是Apache软件基金会的一个项目,它提供了大量...
在Java开发中,Jakarta Commons库提供了许多子项目,如IO、Lang、BeanUtils、Collections、Codec等,每个子项目都专注于特定的领域,如输入/输出操作、字符串处理、对象的创建和复制、集合的扩展以及编码解码等。...
《Apache Jakarta Commons 使用手册》是一部详细介绍Apache Jakarta Commons项目下的各种Java组件的专业书籍。该书由Will Iverson编写,旨在为开发者提供一个全面深入理解并应用这些组件的学习资源。Apache Jakarta ...
Commons BeanUtils库提供了一种简化Java Bean属性操作的方法。它包含以下组件: - BeanUtils:提供对Bean属性进行读取和设置的方法。 - BeanUtilsBean:底层支持Bean操作的工具类。 - PropertyUtils:类似于...
在阅读《Jakarta Commons Cookbook》时,你可以学习如何有效地利用这些组件来提升你的Java项目。例如,了解如何使用` FileUtils.copyFile()`方法复制文件,或通过` StringUtils.join()`将数组元素连接成字符串。此外...
除了上述组件外,Jakarta Commons 还包括 BeanUtils、Codec、 Digester 等,它们提供了诸如对象属性映射、编码解码、XML 解析等功能,大大简化了 Java 开发中的常见任务。 通过了解和使用 Jakarta Commons,开发者...
### Jakarta Commons概述与...总之,Jakarta Commons及其组成部分Commons Lang为Java开发者提供了极其宝贵的资源。通过对这些工具的深入了解和实践应用,不仅能提高开发效率,还能进一步增强代码的可读性和可维护性。
Apache Jakarta Commons 是一组由 Apache 软件基金会提供的 Java 库,这些库旨在解决常见的编程问题,提供便捷的功能,减少开发人员重复编写基础代码的工作。Jakarta Commons 包含了许多子项目,每个子项目专注于...
8. **增强Java核心库之BeanUtils与Lang**:介绍BeanUtils和Lang组件,分别用于简化Bean操作和提供通用函数。 9. **池化与DBCP**:讨论池化技术,特别是DBCP组件,用于创建和管理数据库连接池。 10. **编码与解码...
Jakarta Commons 是 Apache 软件基金会的一个项目集合,它提供了大量的可重用 Java 类库,旨在简化开发人员的工作。这些类库覆盖了从文件上传、缓存处理到网络通信等多个领域,极大地丰富了Java 开发者的工具箱。...
commons-email 提供一组用于发送Email的API,它基于Java Mail API基础之上并进行了简化 commons-exec 处理外部进程的执行或管理外部环境 commons-fileupload 使得在你可以在应用和Servlet中容易的加入强大和高性能...
在Jakarta项目中,"commons"包是一个核心部分,提供了许多实用的工具类和模块化服务,帮助开发者简化Java编程。下面将详细阐述Jakarta项目的commons包以及其中各个文件的用途。 1. **Commons概述** Commons包是...
Jakarta Commons是Apache软件基金会的一个项目,它包含了一系列实用的、独立的Java类库,旨在简化开发过程,提高代码复用性。这本书通过实例和实践指南,帮助读者理解和应用Jakarta Commons中的各种组件。 该书可能...
在学习Jakarta Commons时,开发者应重点关注其设计原则、类的设计模式、以及如何利用这些工具类提高代码的简洁性和可维护性。通过阅读源码,可以学习到如何优雅地处理常见的编程问题,例如异常处理、线程安全、性能...
Apache Jakarta Commons是Apache软件基金会的一个项目,它提供了大量的Java类库,这些类库解决了常见的编程任务,包括输入/输出、数学计算、字符串处理、日期和时间操作等。 本书的核心知识点可以分为以下几个部分...
Apache Jakarta Commons是Apache软件基金会的一个项目集合,它提供了一系列实用工具类库,旨在简化Java开发。这个项目的主要目标是创建可重用的Java组件,这些组件涵盖了从数据处理到网络通信的各种领域。Iverson的...