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