自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

求求你了,不要再自己實(shí)現(xiàn)這些邏輯了,開源工具類不香嗎?

開發(fā) 開發(fā)工具
最近公司來(lái)了一批實(shí)習(xí)生,阿粉負(fù)責(zé)帶一個(gè)。這位小師弟說(shuō)實(shí)話,基本功很扎實(shí),做事也非??孔V,深得阿粉真?zhèn)鳌?

 最近公司來(lái)了一批實(shí)習(xí)生,阿粉負(fù)責(zé)帶一個(gè)。這位小師弟說(shuō)實(shí)話,基本功很扎實(shí),做事也非??孔V,深得阿粉真?zhèn)鳌?/p>

[[325347]]

 

不過(guò)最近給其 Review 代碼的時(shí)候,阿粉發(fā)現(xiàn)小師弟有些代碼邏輯有些繁瑣,有些代碼阿粉看來(lái)可以用一些開源工具類實(shí)現(xiàn),不需要自己重復(fù)實(shí)現(xiàn)。

不過(guò)這也是正常的,阿粉剛?cè)胄械臅r(shí)候?qū)懙拇a也是這樣,這幾年慢慢接觸了一些開源工具類,逐漸積累。現(xiàn)在寫代碼才會(huì)直接用工具類替換自己實(shí)現(xiàn)的這些繁瑣的邏輯。

于是阿粉給小師弟分享了幾個(gè)自己常用的開源工具類,小師弟學(xué)完直呼:『666』。

 

 

 

[[325348]]

 

這里阿粉拋磚引玉,分享幾個(gè)常用的工具類,希望幫助到剛?cè)胄械耐瑢W(xué)們。其他編程老司機(jī)如果還有其他好用的工具類,歡迎評(píng)論區(qū)分享。

下文主要分享這幾個(gè)方向的常用工具類:

 

 

 

 

字符串相關(guān)工具類

Java 中 String 應(yīng)該是日常用的最多一個(gè)類吧,平常我們很多代碼需要圍繞 String ,做一些處理。

JDK 提供 String API 雖然比較多,但是功能比較基礎(chǔ),通常我們需要結(jié)合 String 多個(gè)方法才能完成一個(gè)業(yè)務(wù)功能。

下面介紹一下 Apache 提供的一個(gè)工具類 StringUtils.

Maven Pom 信息如下:

  1. <dependency> 
  2.     <groupId>org.apache.commons</groupId> 
  3.     <artifactId>commons-lang3</artifactId> 
  4.     <version>3.10</version> 
  5. </dependency> 

commons-lang 有兩個(gè)版本,一個(gè)是 commons-lang3 ,一個(gè)是 commons-lang 。

commons-lang 是老版本,已經(jīng)很久沒(méi)有維護(hù)了。

commons-lang3 是一直在維護(hù)的版本,推薦直接使用這個(gè)版本。

注意:如果你系統(tǒng)已經(jīng)有 commons-lang,注意如果直接替換成 commons-lang3,將會(huì)編譯錯(cuò)誤。commons-lang3 中相關(guān)類與 commons-lang 一樣,但是包名不一樣。

判斷字符串是否為空

判斷字符串是否為空,想必每個(gè)人應(yīng)該都寫過(guò)吧:

 

  1. if (null == str || str.isEmpty()) { 
  2.  

雖然這段代碼非常簡(jiǎn)單,但是說(shuō)實(shí)話,阿粉以前還是在這里犯過(guò)空指針的異常的。

 

使用 StringUtils ,上面代碼可以替換下面這樣:

 

  1. if (StringUtils.isEmpty(str)) { 
  2.  

StringUtils 內(nèi)部還有一個(gè)方法 isBlank,也是用來(lái)判斷字符串是否為空,兩個(gè)方法比較相近,比較搞混,主要區(qū)別如下:

 

  1. // 如果字符串都是空格的話, 
  2. StringUtils.isBlank(" ")       = true
  3. StringUtils.isEmpty(" ")       = false;   

判斷字符串是否為空,使用頻率非常高,這里大家可以使用 IDEA Prefix 的功能,輸入直接生成判空語(yǔ)句。

 

 

 

 

字符串固定長(zhǎng)度

這個(gè)通常用于字符串需要固定長(zhǎng)度的場(chǎng)景,比如需要固定長(zhǎng)度字符串作為流水號(hào),若流水號(hào)長(zhǎng)度不足,,左邊補(bǔ) 0 。

這里當(dāng)然可以使用 String#format 方法,不過(guò)阿粉覺(jué)得比較麻煩,這里可以這樣使用:

 

  1. // 字符串固定長(zhǎng)度 8位,若不足,往左補(bǔ) 0 
  2. StringUtils.leftPad("test", 8, "0"); 

另外還有一個(gè) StringUtils#rightPad,這個(gè)方法與上面方法正好相反。

字符串關(guān)鍵字替換

StringUtils 提供一些列的方法,可以替換某些關(guān)鍵字:

 

  1. // 默認(rèn)替換所有關(guān)鍵字 
  2. StringUtils.replace("aba""a""z")   = "zbz"
  3. // 替換關(guān)鍵字,僅替換一次 
  4. StringUtils.replaceOnce("aba""a""z")   = "zba"
  5. // 使用正則表達(dá)式替換 
  6. StringUtils.replacePattern("ABCabc123""[^A-Z0-9]+""")   = "ABC123"; 
  7. ....    

字符串拼接

字符串拼接是個(gè)常見的需求,簡(jiǎn)單辦法使用 StringBuilder 循環(huán)遍歷拼接:

 

  1. String[] array = new String[]{"test""1234""5678"}; 
  2. StringBuilder stringBuilder = new StringBuilder(); 
  3.  
  4. for (String s : array) { 
  5.     stringBuilder.append(s).append(";"); 
  6. // 防止最終拼接字符串為空  
  7. if (stringBuilder.length() > 0) { 
  8.     stringBuilder.deleteCharAt(stringBuilder.length() - 1); 
  9. System.out.println(stringBuilder.toString()); 

上面業(yè)務(wù)代碼不太難,但是需要注意一下上面這段代碼非常容易出錯(cuò),容易拋出 StringIndexOutOfBoundsException。

這里我們可以直接使用以下方法獲取拼接之后字符串:

 

  1. StringUtils.join(["a""b""c"], ",")    = "a,b,c" 

StringUtils 只能傳入數(shù)組拼接字符串,不過(guò)我比較喜歡集合拼接,所以再推薦下 Guava 的 Joiner。

實(shí)例代碼如下:

 

  1. String[] array = new String[]{"test""1234""5678"}; 
  2. List<String> list=new ArrayList<>(); 
  3. list.add("test"); 
  4. list.add("1234"); 
  5. list.add("5678"); 
  6. StringUtils.join(array, ","); 
  7.  
  8. // 逗號(hào)分隔符,跳過(guò) null 
  9. Joiner joiner=Joiner.on(",").skipNulls(); 
  10. joiner.join(array); 
  11. joiner.join(list); 

字符串拆分

有字符串拼接,就會(huì)有拆分字符串的需求,同樣的 StringUtils 也有拆分字符串的方法。

 

  1. StringUtils.split("a..b.c"'.')   = ["a""b""c"
  2. StringUtils.splitByWholeSeparatorPreserveAllTokens("a..b.c"".")= ["a","""b""c"

ps:注意以上兩個(gè)方法區(qū)別。

StringUtils 拆分之后得到是一個(gè)數(shù)組,我們可以使用 Guava 的

 

  1. Splitter splitter = Splitter.on(","); 
  2. // 返回是一個(gè) List 集合,結(jié)果:[ab, , b, c] 
  3. splitter.splitToList("ab,,b,c"); 
  4. // 忽略空字符串,輸出結(jié)果 [ab, b, c] 
  5. splitter.omitEmptyStrings().splitToList("ab,,b,c"

StringUtils 內(nèi)部還有其他常用的方法,小伙伴可以自行查看其 API。

日期相關(guān)工具類

DateUtils/DateFormatUtils

JDK8 之前,Java 只提供一個(gè) Date 類,平常我們需要將 Date 按照一定格式轉(zhuǎn)化成字符串,我們需要使用 SimpleDateFormat。

 

  1. SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
  2. // Date 轉(zhuǎn) 字符串 
  3. simpleDateFormat.format(new Date()); 
  4. // 字符串 轉(zhuǎn) Date 
  5. simpleDateFormat.parse("2020-05-07 22:00:00"); 

代碼雖然簡(jiǎn)單,但是這里需要注意 SimpleDateFormat,不是線程安全的,多線程環(huán)境一定要注意使用安全。

這里阿粉推薦 commons-lang3 下的時(shí)間工具類DateUtils/DateFormatUtils,解決 Date 與字符串轉(zhuǎn)化問(wèn)題。

ps:吐槽一下,你們工程中有沒(méi)有多個(gè)叫 DateUtils 類?阿粉發(fā)現(xiàn)我們現(xiàn)有工程,多個(gè)模塊有提供這個(gè)類,每個(gè)實(shí)現(xiàn)大同小異。

使用方法非常簡(jiǎn)單:

 

  1. // Date 轉(zhuǎn)化為字符串 
  2. DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"); 
  3. // 字符串 轉(zhuǎn) Date 
  4. DateUtils.parseDate("2020-05-07 22:00:00","yyyy-MM-dd HH:mm:ss"); 

除了格式轉(zhuǎn)化之外,DateUtils 還提供時(shí)間計(jì)算的相關(guān)功能。

 

  1. Date now = new Date(); 
  2. // Date 加 1 天 
  3. Date addDays = DateUtils.addDays(now, 1); 
  4. // Date 加 33 分鐘 
  5. Date addMinutes = DateUtils.addMinutes(now, 33); 
  6. // Date 減去 233 秒 
  7. Date addSeconds = DateUtils.addSeconds(now, -233); 
  8. // 判斷是否 Wie 同一天 
  9. boolean sameDay = DateUtils.isSameDay(addDays, addMinutes); 
  10. // 過(guò)濾時(shí)分秒,若 now 為 2020-05-07 22:13:00 調(diào)用 truncate 方法以后 
  11. // 返回時(shí)間為 2020-05-07 00:00:00 
  12. Date truncate = DateUtils.truncate(now, Calendar.DATE); 

JDK8 時(shí)間類

JDK8 之后,Java 將日期與時(shí)間分為 LocalDate,LocalTime,功能定義更加清晰,當(dāng)然其也提供一個(gè) LocalDateTime,包含日期與時(shí)間。這些類相對(duì)于 Date 類優(yōu)點(diǎn)在于,這些類與 String 類一樣都是不變類型,不但線程安全,而且不能修改。

ps:仔細(xì)對(duì)比 mysql 時(shí)間日期類型 DATE,TIME,DATETIME,有沒(méi)有感覺(jué)差不多

現(xiàn)在 mybatis 等 ORM 框架已經(jīng)支持 LocalDate 與 JDBC 時(shí)間類型轉(zhuǎn)化,所以大家可以直接將時(shí)間字段實(shí)際類型定義為 JDK8 時(shí)間類型,然后再進(jìn)行相關(guān)轉(zhuǎn)化。

如果依然使用的是 Date 類型,如果需要使用新的時(shí)間類型,我們需要進(jìn)行相關(guān)轉(zhuǎn)化。兩者之間進(jìn)行轉(zhuǎn)化, 稍微復(fù)雜一點(diǎn),我們需要顯示指定當(dāng)前時(shí)區(qū)。

 

  1. Date now = new Date(); 
  2. // Date-----> LocalDateTime 這里指定使用當(dāng)前系統(tǒng)默認(rèn)時(shí)區(qū) 
  3. LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); 
  4. // LocalDateTime------> Date 這里指定使用當(dāng)前系統(tǒng)默認(rèn)時(shí)區(qū) 
  5. Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); 

接下來(lái)我們使用 LocalDateTime 進(jìn)行字符串格式化。

 

  1. // 按照 yyyy-MM-dd HH:mm:ss 轉(zhuǎn)化時(shí)間 
  2. LocalDateTime dateTime = LocalDateTime.parse("2020-05-07 22:34:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 
  3. // 將 LocalDateTime 格式化字符串 
  4. String format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dateTime); 

另外我們使用 LocalDateTime 獲取當(dāng)前時(shí)間年份,月份特別簡(jiǎn)單:

 

  1. LocalDateTime now = LocalDateTime.now(); 
  2. // 年 
  3. int year = now.getYear(); 
  4. // 月 
  5. int month = now.getMonthValue(); 
  6. // 日 
  7. int day = now.getDayOfMonth(); 

最后我們還可以使用 LocalDateTime 進(jìn)行日期加減,獲取下一天的時(shí)間:

 

  1. LocalDateTime now = LocalDateTime.now(); 
  2. // 當(dāng)前時(shí)間加一天 
  3. LocalDateTime plusDays = now.plusDays(1l); 
  4. // 當(dāng)前時(shí)間減一個(gè)小時(shí) 
  5. LocalDateTime minusHours = now.minusHours(1l); 
  6. // 還有很多其他方法 

總之 JDK8 提供的時(shí)間類非常好用,還沒(méi)用過(guò)小伙伴,可以嘗試下。

集合/數(shù)組相關(guān)

集合與數(shù)組我們?nèi)粘R残枰?jīng)常使用,也需要對(duì)其進(jìn)行判空:

 

  1. if (null == list || list.isEmpty()) { 
  2.  

ps: 數(shù)組、Map 集合與其類似

上面代碼如字符串判空一樣寫起來(lái)都非常簡(jiǎn)單,但是也比較容易寫出會(huì)拋出空指針異常的代碼。這里我們可以使用 commons-collections 提供工具類。

pom 信息:

  1. <dependency> 
  2.     <groupId>org.apache.commons</groupId> 
  3.     <artifactId>commons-collections4</artifactId> 
  4.     <version>4.4</vesion> 
  5. </dependency> 

ps: 還有一個(gè)低版本的 ,artifactId 為 commons-collections

我們可以使用 CollectionUtils/MapUtils進(jìn)行判空判斷。

 

  1. // List/Set 集合判空 
  2. if(CollectionUtils.isEmpty(list)){ 
  3.  
  4. // Map 等集合進(jìn)行判空 
  5. if (MapUtils.isEmpty(map)) { 
  6.      

至于數(shù)組判空判斷需要使用 commons-lang 下的 ArrayUtils進(jìn)行判斷:

 

  1. // 數(shù)組判空 
  2. if (ArrayUtils.isEmpty(array)) { 
  3.      

除此之外還有一些列的對(duì)于集合增強(qiáng)方法,比如快速將數(shù)組加入到現(xiàn)有集合中:

 

  1. List<String> listA = new ArrayList<>(); 
  2. listA.add("1"); 
  3. listA.add("2"); 
  4. listA.add("3"); 
  5. String[] arrays = new String[]{"a""b""c"}; 
  6. CollectionUtils.addAll(listA, arrays); 

其他方法感興趣同學(xué)可以再自行研究下,另外 Guava 中也有提供對(duì)于集合的操作增強(qiáng)類 Lists/Maps,這個(gè)可以看下阿粉之前寫的:老司機(jī)阿粉帶你玩轉(zhuǎn) Guava 集合類。

I/O 相關(guān)

JDK 有提供一系列的類可以讀取文件等,不過(guò)阿粉覺(jué)得那些類有些晦澀難懂,實(shí)現(xiàn)一個(gè)小功能可能還要寫好多代碼,而且還不一定能寫對(duì)。

阿粉推薦一下 Apache 提供的 commons-io 庫(kù),增強(qiáng) I/O 操作,簡(jiǎn)化操作難度。pom 信息:

  1. <dependency> 
  2.     <groupId>commons-io</groupId> 
  3.     <artifactId>commons-io</artifactId> 
  4.     <version>2.6</version> 
  5. </dependency> 

FileUtils-文件操作工具類

文件操作工具類提供一系列方法,可以讓我們快速讀取寫入文件。

快速實(shí)現(xiàn)文件/文件夾拷貝操作 ,FileUtils.copyDirectory/FileUtils.copyFile

 

  1. // 拷貝文件 
  2. File fileA = new File("E:\\test\\test.txt"); 
  3. File fileB = new File("E:\\test1\\test.txt"); 
  4. FileUtils.copyFile(fileA,fileB); 

使用 FileUtils.listFiles 獲取指定文件夾上所有文件

 

  1. // 按照指定文件后綴如java,txt等去查找指定文件夾的文件 
  2. File directory = new File("E:\\test"); 
  3. FileUtils.listFiles(directory, new String[]{"txt"}, false); 

使用 FileUtils.readLines 讀取該文件所有行。

 

  1. // 讀取指定文件所有行 不需要使用 while 循環(huán)讀取流了 
  2. List<String> lines = FileUtils.readLines(fileA) 

有讀就存在寫,可以使用 FileUtils.writeLines,直接將集合中數(shù)據(jù),一行行寫入文本。

 

  1. // 可以一行行寫入文本 
  2. List<String> lines = new ArrayList<>(); 
  3. ..... 
  4. FileUtils.writeLines(lines) 

IOUtils-I/O 操作相關(guān)工具類

FileUtils 主要針對(duì)相關(guān)文件操作,IOUtils 更加針對(duì)底層 I/O,可以快速讀取 InputStream。實(shí)際上 FileUtils 底層操作依賴就是 IOUtils。

IOUtils可以適用于一個(gè)比較試用的場(chǎng)景,比如支付場(chǎng)景下,HTTP 異步通知場(chǎng)景。如果我們使用 JDK 原生方法寫:

從 Servlet 獲取異步通知內(nèi)容

 

  1. byte[] b = null
  2. ByteArrayOutputStream baos = null
  3. String respMsg = null
  4. try { 
  5.     byte[] buffer = new byte[1024]; 
  6.     baos = new ByteArrayOutputStream(); 
  7.    // 獲取輸入流 
  8.     InputStream in = request.getInputStream(); 
  9.     for (int len = 0; (len = in.read(buffer)) > 0; ) { 
  10.         baos.write(buffer, 0, len); 
  11.     } 
  12.     b = baos.toByteArray(); 
  13.     baos.close(); 
  14.    // 字節(jié)數(shù)組轉(zhuǎn)化成字符串 
  15.     String reqMessage = new String(b, "utf-8"); 
  16. } catch (IOException e) { 
  17.    
  18. } finally { 
  19.     if (baos != null) { 
  20.         try { 
  21.             baos.close(); 
  22.         } catch (IOException e) { 
  23.             
  24.         } 
  25.     } 

上面代碼說(shuō)起來(lái)還是挺復(fù)雜的。不過(guò)我們使用 IOUtils,一個(gè)方法就可以簡(jiǎn)單搞定:

 

  1. // 將輸入流信息全部輸出到字節(jié)數(shù)組中 
  2. byte[] b = IOUtils.toByteArray(request.getInputStream()); 
  3. // 將輸入流信息轉(zhuǎn)化為字符串 
  4. String resMsg = IOUtils.toString(request.getInputStream()); 

ps: InputStream 不能被重復(fù)讀取

計(jì)時(shí)

編程中有時(shí)需要統(tǒng)計(jì)代碼的的執(zhí)行耗時(shí),當(dāng)然執(zhí)行代碼非常簡(jiǎn)單,結(jié)束時(shí)間與開始時(shí)間相減即可。

 

  1. long start = System.currentTimeMillis();   //獲取開始時(shí)間 
  2.  
  3. //其他代碼 
  4. //... 
  5. long end = System.currentTimeMillis(); //獲取結(jié)束時(shí)間 
  6.  
  7. System.out.println("程序運(yùn)行時(shí)間: " + (end - start) + "ms"); 

雖然代碼很簡(jiǎn)單,但是非常不靈活,默認(rèn)情況我們只能獲取 ms 單位,如果需要轉(zhuǎn)換為秒,分鐘,就需要另外再計(jì)算。

這里我們介紹 Guava Stopwatch 計(jì)時(shí)工具類,借助他統(tǒng)計(jì)程序執(zhí)行時(shí)間,使用方式非常靈活。

commons-lang3 與 Spring-core 也有這個(gè)工具類,使用方式大同小異,大家根據(jù)情況選擇。

 

  1. // 創(chuàng)建之后立刻計(jì)時(shí),若想主動(dòng)開始計(jì)時(shí) 
  2. Stopwatch stopwatch = Stopwatch.createStarted(); 
  3. // 創(chuàng)建計(jì)時(shí)器,但是需要主動(dòng)調(diào)用 start 方法開始計(jì)時(shí) 
  4. // Stopwatch stopwatch = Stopwatch.createUnstarted(); 
  5. // stopWatch.start(); 
  6. // 模擬其他代碼耗時(shí) 
  7. TimeUnit.SECONDS.sleep(2l); 
  8.  
  9. // 當(dāng)前已經(jīng)消耗的時(shí)間 
  10. System.out.println(stopwatch.elapsed(TimeUnit.SECONDS));; 
  11.  
  12. TimeUnit.SECONDS.sleep(2l); 
  13.  
  14. // 停止計(jì)時(shí) 未開始的計(jì)時(shí)器調(diào)用 stop 將會(huì)拋錯(cuò) IllegalStateException 
  15. stopwatch.stop(); 
  16. // 再次統(tǒng)計(jì)總耗時(shí) 
  17. System.out.println(stopwatch.elapsed(TimeUnit.SECONDS));; 
  18. // 重新開始,將會(huì)在原來(lái)時(shí)間基礎(chǔ)計(jì)算,若想重新從 0開始計(jì)算,需要調(diào)用 stopwatch.reset() 
  19. stopwatch.start(); 
  20. TimeUnit.SECONDS.sleep(2l); 
  21. System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); 

輸出結(jié)果為:

 

總結(jié)

今天阿粉拋磚引玉,介紹了字符串、日期、數(shù)組/集合、I/O、計(jì)時(shí)等工具類,簡(jiǎn)化日常業(yè)務(wù)代碼。大家看完可以嘗試一下,不得不說(shuō),這些工具類真香!

責(zé)任編輯:華軒 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2020-10-12 10:45:44

nullava程序員

2020-12-11 09:24:19

Elasticsear存儲(chǔ)數(shù)據(jù)

2021-05-11 07:10:18

標(biāo)準(zhǔn)庫(kù)DjangoOS

2024-02-01 08:21:40

2020-12-15 08:06:45

waitnotifyCondition

2020-06-15 08:12:51

try catch代碼處理器

2019-11-18 10:05:43

程序員技能開發(fā)者

2019-11-18 10:16:37

工程師開發(fā)網(wǎng)絡(luò)

2021-12-05 23:17:18

iOS蘋果系統(tǒng)

2025-02-10 08:05:03

2020-09-22 09:05:45

MySQLUTF-8utf8mb4

2022-10-27 21:34:28

數(shù)據(jù)庫(kù)機(jī)器學(xué)習(xí)架構(gòu)

2020-11-09 08:22:29

程序員 IT科技

2020-01-21 21:15:16

WiFi網(wǎng)絡(luò)WiFi6

2021-12-02 06:34:34

GraylogELK日志

2021-12-03 10:46:49

ELKGraylog運(yùn)維

2020-12-01 11:18:34

對(duì)外接口枚舉

2021-09-30 06:13:36

打印日志error

2020-07-03 15:10:35

Java Rust 開發(fā)

2021-01-11 08:03:30

阿里中臺(tái)項(xiàng)目
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)