|
摘要
目前Commons Proper中有33個(gè)項(xiàng)目,Commons Sandbox中有22個(gè)項(xiàng)目,故而,任何一類Java項(xiàng)目都有其存在的意義。
只有當(dāng)密鑰滿足所有這些條件時(shí),應(yīng)用程序才會(huì)查詢數(shù)據(jù)庫(kù),檢查該密鑰是否合法。 /**
* 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類中提供的各種方法,根據(jù)我們先前定義的所有規(guī)則對(duì)字符串進(jìn)行驗(yàn)證。isBlank()方法檢查字符串是否為空。deleteWhitespace()方法確保字符串不包含空格。然后我們使用split()方法對(duì)字符串進(jìn)行分隔,并使用isNumeric()、containsOnly()和indexOf()方法對(duì)密鑰的兩部分進(jìn)行驗(yàn)證。請(qǐng)注意,盡管在J2SE中已經(jīng)有了indexOf()方法,最好使用StringUtils中的indexOf()。與J2SE indexOf()方法不同,使用StringUtils indexOf()時(shí)無(wú)需擔(dān)心空指針的問(wèn)題。觸發(fā)NullPointerException被認(rèn)為是Java程序員最常犯的錯(cuò)誤。Lang可以確保您不會(huì)犯同樣的錯(cuò)誤。即使向indexOf()或其他此類方法傳遞一個(gè)null,都不會(huì)引發(fā)NullPointerException。indexOf()將直接返回-1。 這樣,只需幾行簡(jiǎn)單代碼,就可以實(shí)現(xiàn)相應(yīng)的功能,而采用其他方法需要編寫(xiě)很多行代碼,而且十分麻煩。如果使用清單2中所示的主方法執(zhí)行checkLicenseKey()方法,所得到的結(jié)果如清單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大部分用于進(jìn)行字符串操作的方法都隸屬于org.apache.commons.lang.StringUtils,但也有其他的類可以使用。CharUtils和CharSetUtils分別提供使用字符和字符集的實(shí)用方法。WordUtils是在2.0版中首次出現(xiàn)的類,用于承載專門用于處理字的實(shí)用方法。不過(guò),由于字符串和字的處理上有大量的重疊操作,使得此類似乎有點(diǎn)沒(méi)有存在的必要了。RandomStringUtils類可以根據(jù)各種規(guī)則生成隨機(jī)字符串。 現(xiàn)在,讓我們了解一下Lang的另一個(gè)有用的方面:處理日期和時(shí)間的能力。 時(shí)間技術(shù) 在Java中處理日期和時(shí)間是一件相當(dāng)棘手的事。如果要使用java.text.SimpleDateFormat、java.util.Calendar、java.util.Date等類,需要一定時(shí)間來(lái)適應(yīng),還需要對(duì)每一個(gè)涉及到的類和接口非常了解,才能順利地處理日期和時(shí)間。 Lang組件徹底地簡(jiǎn)化了日期的處理,并可對(duì)其進(jìn)行格式化。您可以輕松地格式化日期以進(jìn)行顯示、比較日期、舍入或截?cái)嗳掌冢踔聊塬@取特定范圍內(nèi)的所有日期。 清單4. 處理日期和時(shí)間 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類的部分功能。還有其他許多方法可以進(jìn)行同樣的操作,但輸入格式不同。故而,如果萬(wàn)一您必須分析和格式化一個(gè)日期值,只需要借助提供的方法之一,利用一行代碼就可以實(shí)現(xiàn)了。 執(zhí)行清單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中,我們創(chuàng)建了兩個(gè)日期,這兩個(gè)日期僅有一秒的差別。然后使用isSameInstant()和isSameDay()方法檢查這兩個(gè)日期是否相同。接下來(lái)將日期進(jìn)行舍入和截?cái)啵缓笫褂迷跀?shù)組中指定的各種格式對(duì)特殊日期用例進(jìn)行解析。 將您的應(yīng)用程序集成到第三方應(yīng)用程序時(shí),經(jīng)常不能完全確定輸入的格式。我曾經(jīng)做過(guò)一個(gè)對(duì)舊版應(yīng)用程序的集成,對(duì)于每個(gè)問(wèn)題,該應(yīng)用程序似乎總是有三個(gè)答案。所以,如果必須對(duì)此類應(yīng)用程序提供的日期進(jìn)行解析,您需要提供三個(gè)和四個(gè)不同的日期格式。清單4中使用parseDate()方法就是為了完成這項(xiàng)任務(wù)。這樣,即使輸入有變化,仍然能更對(duì)日期進(jìn)行解析。還要注意,數(shù)組內(nèi)模式的順序與輸入的順序并不相同,但該方法仍然找到了適當(dāng)?shù)哪J?,并?jù)此進(jìn)行解析。 最后,我們按照ISO_TIME_NO_T_FORMAT格式(HH:mm:ss)對(duì)日期進(jìn)行格式化并打印輸入。現(xiàn)在我們將了解使用Lang生成常用方法toString()。 生成toString()方法 經(jīng)常要用到equals()、toString()和hashCode()方法。不過(guò),談到實(shí)際編寫(xiě)這些方法的實(shí)現(xiàn)時(shí),不僅我們大多數(shù)人不愿意這樣做,而且我們也不能確定如何準(zhǔn)確簡(jiǎn)單地編寫(xiě)這些方法。生成器程序包提供了一些實(shí)用類,可以幫助您方便地創(chuàng)建這些方法的實(shí)現(xiàn)。大多數(shù)情況下,只需要一行代碼即可。下面我們將了解Lang的toString功能。 toString()方法 您可能沒(méi)有注意到,在清單4中,即使我們向System.out.println()傳遞一個(gè)java.util.Date對(duì)象,所獲得的輸出仍然是正確的日期和時(shí)間顯示。傳遞對(duì)象引用時(shí),將自動(dòng)調(diào)用toString()方法,所以可以實(shí)現(xiàn)這一點(diǎn)。那么,在我們的示例中實(shí)際上調(diào)用了java.util.Date類的toString()方法,我們能夠得到正確的輸出是因?yàn)橛腥酥貙?xiě)了java.util.Date類中的java.lang.Object類的toString()方法。 如果沒(méi)有重寫(xiě)toString()方法,則獲得的輸出只是類名稱和hashcode的名稱。將不會(huì)顯示類中的任何數(shù)據(jù)。所以,如果編寫(xiě)了一個(gè)新類,且希望能得到正確的打印輸出,則需要重寫(xiě)該類中的toString()方法。 清單6. toString()方法 public class Computer {
String processor;
String color;
int cost;
/** Creates a new instance of Computer */
public Computer(String processor, String color, int cost) {
this.processor=processor;
this.color=color;
this.cost=cost;
}
public static void main(String[] args) {
Computer myComp=new Computer("Pentium","black",1000);
System.out.println(myComp);
}
public String toString(){
return ToStringBuilder.reflectionToString(this);
/*
return ToStringBuilder.reflectionToString(this
, ToStringStyle.SHORT_PREFIX_STYLE);
return ToStringBuilder.reflectionToString(this
, ToStringStyle.MULTI_LINE_STYLE);
return new ToStringBuilder(this)
.append("processor", processor).toString();
*/
}
} 清單6演示了具有三個(gè)字段的Computer類。其中值得關(guān)注的是toString()方法。調(diào)用reflectionToString()方法可以判斷哪些是類中的字段,然后打印其名稱和值。main()方法中,我們只創(chuàng)建了該類的一個(gè)實(shí)例,然后將其打印出來(lái)。該類的輸出為dev2dev.Computer@f6a746[processor=Pentium,color=black,cost=1000]。因而,如果不希望花太多精力,但又需要您的類有toString()實(shí)現(xiàn),最簡(jiǎn)單的方法莫過(guò)于將這兩行代碼復(fù)制并粘貼到您的所有類中。如果希望更好地控制生成的結(jié)果,請(qǐng)參見(jiàn)注釋中提到的選項(xiàng)。通過(guò)創(chuàng)建ToStringBuilder的新實(shí)例,可以對(duì)輸出應(yīng)用各種樣式,甚至生成全部輸出。如果按照列出的順序執(zhí)行了全部四個(gè)返回語(yǔ)句,則輸出如清單7所示。 清單7. 基于ToStringBuilder方法的四個(gè)可能輸出 1) dev2dev.Computer@f6a746[processor=Pentium,color=black,cost=1000] 2) Computer[processor=Pentium,color=black,cost=1000] 3) dev2dev.Computer@f6a746[ processor=Pentium color=black cost=1000 ] 4) dev2dev.Computer@192d342[processor=Pentium]對(duì)象比較與排序 經(jīng)常需要對(duì)數(shù)據(jù)對(duì)象進(jìn)行比較,并據(jù)此進(jìn)行排序。那么我們?nèi)绾螌?duì)清單6中所給出的Computer類的對(duì)象進(jìn)行比較和排序呢? 您猜猜!讓我們使用Lang根據(jù)計(jì)算機(jī)的成本對(duì)Computer對(duì)象進(jìn)行排序。若要比較對(duì)象,需要實(shí)現(xiàn)java.lang.Comparable接口。此接口具有惟一的方法compareTo(Object)。此方法實(shí)現(xiàn)將當(dāng)前對(duì)象和傳遞給此方法的對(duì)象進(jìn)行比較。如果此對(duì)象小于、等于或大于指定的對(duì)象,此方法將分別返回負(fù)數(shù)、零或正數(shù)。 為了對(duì)Computer對(duì)象進(jìn)行比較,在Computer類中實(shí)現(xiàn)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();
}
然后,為了實(shí)際進(jìn)行比較,我們編寫(xiě)一個(gè)名為ComputerSor的簡(jiǎn)單類,如清單9中所示。我們只向ArrayList添加三個(gè)對(duì)象,然后進(jìn)行排序。清單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);
}
}
執(zhí)行ComputerSort時(shí),將看到對(duì)象根據(jù)cost字段的值進(jìn)行了排序。CompareToBuilder與ToStringBuilder類似,也有一個(gè)基于反射的用法選項(xiàng)。我們已對(duì)清單8中的compareTo()方法中的位元進(jìn)行了注釋,因?yàn)?,在此種情況下,反射選項(xiàng)將比較所有字段,最終獲得不正確的結(jié)果。如果既不希望比較當(dāng)前類中的字段,也不希望比較其超類中的字段,CompareToBuilder也提供了可以用于此用途的方法。執(zhí)行ComputerSort類的輸出如清單10中所示。清單10. 排序后的Computer對(duì)象 [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]] 結(jié)束語(yǔ) Harshad Oak是Java J2EE門戶網(wǎng)站IndicThreads.com的創(chuàng)始人。他編寫(xiě)了Pro Jakarta Commons和Oracle JDeveloper 10g:Empowering J2EE Development,并與人合著了Java 2 Enterprise Edition 1.4 Bible。他還是Rightrix Solutions的創(chuàng)始人。 |
|
|
來(lái)自: smoking_boy > 《我的圖書(shū)館》