幾款Java常用基礎工具庫


通用工具類(字符串、時間格式化、BeanUtils、IO)

1. commons-lang3庫

1.1. org.apache.commons.lang3.StringUtils類

日常代碼中,我們經常和String字符串打交道,經常對字符串進行處理,稍微不注意的話,很容易出現類似NullPointerException這種簡單的錯誤,我們經常寫各種if來判斷處理這些非業務的邏輯。這時,我們可以利用大牛apache的輪子,通過其StringUtils里面的一些常用方法,改善我們的代碼,讓我們的業務代碼更簡潔、優雅。示例代碼: 

@Slf4j
 public class AppTest {
 @Test
 public void stringUtils(){
 String a = " ";
 String b = null;
 //判斷字符對象是否為空以及內容是否為空串(有空格則認為不是空串)
 log.info("StringUtils.isEmpty(a): {}", StringUtils.isEmpty(a));
 //判斷字符對象是否為空以及內容是否為空串(有空格也會認為是空串)
 log.info("StringUtils.isBlank(a): {}", StringUtils.isBlank(a));
 //當b=null時,如果b.trim()則會報空指針異常,使用StringUtils.trim(b)可以避免
 log.info("StringUtils.trim(d): {}", StringUtils.trim(b));
 
 String num = "12.3";
 //當b=null時,如果b.trim()則會報空指針異常,使用StringUtils.trim(b)可以避免
 log.info("org.apache.commons.lang3.StringUtils.isNumericSpace(): {} isNumber: {}", num, StringUtils.isNumericSpace(b));
 log.info("com.alibaba.druid.util.StringUtils.isNumber(): {} isNumber: {}", num, com.alibaba.druid.util.StringUtils.isNumber(num));
 }
 }

注意:common-lang3中的StringUtils. isNumeric()或isNumericSpace()並不能判斷字符串中帶小數點的數字值字符為數字。可以通過com.alibaba.druid.util.StringUtils.isNumber(str),此方法來判斷。

1.2 org.apache.commons.lang3.time.DateFormatUtils/DateUtils

時間轉換工具類:

 @Test
 public void dateFormatUtils() throws Exception{
 String pattern = "yyyy-MM-dd HH:mm:ss";
 String timeStr = DateFormatUtils.format(new Date(), pattern);
 long timestamp = DateUtils.parseDate(timeStr, pattern).getTime();
 log.info("==> current time: {}", timeStr);
 log.info("==> current time timestamp: {}", timestamp);
 }

總結

  • StringUtils.isEmpty(str)/StringUtils.isNotEmpty(str): 判斷字符對象是否為null或空串(有空格則認為不是空串)
  • StringUtils.isBlank(str)/StringUtils.isNotBlank(str): 判斷字符對象是否為null或空串(有空格也會認為是空串)
  • DateFormatUtils.format(date, pattern): 將Date時間對象按表達式的格式轉換成時間字符串
  • DateUtils.parseDate(timeStr, pattern): 將時間字符串反轉成Date對象
  • ToStringBuilder.reflectionToString(obj): 將對象內容轉換成字符串輸出(下一節有使用到)
  • ...

對於學習某個工具類,我們可以通過Intellij IDEA中可通過打開此類的源代碼,然后通過快捷鍵(MacOS: command+7; Windows: Alt+7)打開查看類方法列表(Structure),從方法名字上大概可以看出具體有那些適合自己使用的方法。

以上示例使用到的jar包可通過maven的pom.xml文件依賴導入:

 <dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.8.1</version>
 </dependency>
 <dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>druid</artifactId>
 <version>1.1.9</version>
 </dependency>

2.common-beanutils庫

Map、JavaBean是我們日常業務代碼中經常使用到的2種類,有時因為業務原因,Map、JavaBean需要相互轉換copy啥的操作時,如果手動set/put,字段多的時候,就要吐血了。這里我們推薦使用BeanUtils來簡化我們的代碼

2.1.org.apache.commons.beanutils.BeanUtils類

@Test
 public void beanUtils() throws InvocationTargetException, IllegalAccessException {
 CompanyBean bean = new CompanyBean();
 bean.setId(1);
 bean.setName("中國移動廣州分公司");
 bean.setAddress("廣州市天河區中山大道");
 bean.setTel("020-10086000");
 CompanyBean destObj = new CompanyBean();
 //復制bean之間復制內容, 新對象destObj需要先實例化
 BeanUtils.copyProperties(destObj, bean);
 //ToStringBuilder類來自commons-lang3庫:將對象內容轉換成字符串輸出,方便於日志輸出
 log.info("destObj from BeanUtils.copyProperties: {}", ToStringBuilder.reflectionToString(destObj));
 
 Map<String, Object> map = new HashMap<>();
 map.put("id", 2);
 map.put("name", "中國聯通廣州分公司");
 map.put("address", "廣州市天河區中山大道2號");
 map.put("tel", "020-10000110");
 //將map(key,value)映射成bean
 BeanUtils.populate(destObj, map);
 log.info("destObj from BeanUtils.populate: {}", ToStringBuilder.reflectionToString(destObj));
 //復制對象,與copyProperties()方法比較,這里新對象可以不先實例化
 CompanyBean cloneBean = (CompanyBean)BeanUtils.cloneBean(destObj);
 log.info("cloneBean from BeanUtils.cloneBean: {}", ToStringBuilder.reflectionToString(cloneBean));
 //將JavaBean轉換成Map
 Map newMap = BeanUtils.describe(cloneBean);
 log.info("newMap from BeanUtils.describe: {}", new Gson().toJson(newMap));
 }

日志輸出如下:

 

2019-01-19 13:17:21.064 [main] INFO com.monbuilder.AppTest - destObj from BeanUtils.copyProperties: com.monbuilder.bean.CompanyBean@10683d9d[id=1,name=中國移動廣州分公司,address=廣州市天河區中山大道1號,tel=020-10086000]
2019-01-19 13:17:21.070 [main] INFO com.monbuilder.AppTest - destObj from BeanUtils.populate: com.monbuilder.bean.CompanyBean@10683d9d[id=2,name=中國聯通廣州分公司,address=廣州市天河區中山大道2號,tel=020-10000110]
2019-01-19 13:48:14.966 [main] INFO com.monbuilder.AppTest - newMap from BeanUtils.describe: {"address":"廣州市天河區中山大道2號","name":"中國聯通廣州分公司","tel":"020-10000110","id":"2","class":"class com.monbuilder.bean.CompanyBean"}

總結

  • BeanUtils.copyProperties(destObj, sourceObj): JavaBean之間內容的復制
  • BeanUtils.cloneBean(obj): 復制對象
  • BeanUtils.populate(destObj, sourceMap): Map轉換成JavaBean
  • BeanUtils.describe(bean): 將JavaBean轉換成Map

3.commons-io庫

org.apache.commons.io.IOUtils類

這個io工具類非常有用,當我們在處理流的過程中,經常需要把流與字節數組之間相互轉換,以及在處理完之后,關閉流等等這些操作時,我們需要寫挺多處理邏輯,close時還需要寫if判空啥的,但是使用了這個IOUtil后,我們的處理代碼或簡潔非常多的。

@Test
 public void ioUtils() throws IOException {
 InputStream io = this.getClass().getClassLoader().getResourceAsStream("README.md");
 BufferedReader br = new BufferedReader(new InputStreamReader(io));
 log.info("==> IOUtils.toString(br): {}", IOUtils.toString(br));
 IOUtils.closeQuietly(br);
 IOUtils.closeQuietly(io);
 }
 2019-01-19 14:29:26.140 [main] INFO com.monbuilder.AppTest - ==> IOUtils.toString(br): toolkit-demo,工具類庫使用示例

上面只是簡單的展示將文件流內容轉換成字符串,之后再關閉流,是不是非常簡潔呢?IOUtils里面還有非常多的好方法可以使用,這些可以根據自己在具體的工作場景下,查看IOUtils的方法列表,找到自己需要的方法

總結

IOUtils常用的方法有:

  • IOUtils.closeQuietly(obj): 可關閉流SocketSocketServer等多種對象
  • IOUtils.copy(InputStream, Writer): 復制輸入流
  • IOUtils.write(byte[], OutputStream): 將字節數組轉換成流
  • IOUtils.toByteArray(InputStream): 將輸入流轉換成字節數組
  • IOUtils.toInputStream(String): 將字符串轉換成輸入流
  • IOUtils.toString(InputStream): 將輸入流轉換成字符串

上面介紹的都是來自於apache官方的類庫,還有好多類與方法有待我們發掘使用。另外,還介紹另1個非常有名的工具類庫:guava,來自於Google;功能也有類似的,當然也有很多的擴展使用,本文就不再詳細介紹了。

<dependency>
 <groupId>com.google.guava</groupId>
 <artifactId>guava</artifactId>
 <version>23.2-jre</version>
 </dependency>

JSON工具類

在如今REST API盛行的年代,前后端分離成為標配,json成為兩者之間的傳輸橋梁,在我們工作做打交道肯定非常頻繁咯。在Java開發中,JSON工具類的選擇並不少:

  • fastjson 阿里巴巴出品,轉換快,但表現不夠穩定
  • Gson google出品,使用簡單,輕量
  • Jackson spring官方使用,性能快,轉換快,配置更靈活,不同場景下表現更穩定

比較推薦使用的是Jackson,如果我們使用Spring Boot或Spring Cloud時,構建web項目里面內置的json庫就是Jackson庫。

下面通過Jackson庫簡單封裝成JavaBean/json互轉的工具類:

package com.monbuilder.util;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import java.text.SimpleDateFormat;
 /***
 * JSON轉換工具類
 * @author <a href="mailto:lcbiao34@gmail.com">Builder34</a>
 * @date 2018-11-01 11:14:26
 * */
 @Slf4j
 public class JacksonUtil {
 private static ObjectMapper objectMapper = new ObjectMapper();
 static {
 objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
 objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
 objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
 // 設置輸入時忽略JSON字符串中存在而Java對象實際沒有的屬性
 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 
 //設置不輸出值為 null 的屬性
 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
 }
 /**
 * 將JSON字符串根據指定的Class反序列化成Java對象(轉換過程中出現異常則返回null對象)
 *
 * @param json JSON字符串
 * @param objClass JavaObject對象Class
 * @return 反序列化生成的Java對象
 * */
 public static <T> T toJavaObject(String json, Class<T> objClass) {
 try {
 return objectMapper.readValue(json, objClass);
 } catch (Exception e) {
 log.error("", e);
 return null;
 }
 }
 /**
 * 將Java對象序列化成JSON字符串(轉換過程中出現異常則返回空對象json串"{}")
 *
 * @param obj 待序列化生成JSON字符串的Java對象
 * @return JSON字符串
 */
 public static String toJsonString(Object obj) {
 try {
 return objectMapper.writeValueAsString(obj);
 } catch (Exception e) {
 log.error("",e);
 }
 return "{}";
 }
 }

運用上面的工具類,示例:

 

@Test
 public void jsonUtils(){
 CompanyBean bean = new CompanyBean();
 bean.setId(1);
 bean.setName("中國移動廣州分公司");
 bean.setAddress("廣州市天河區中山大道1號");
 bean.setTel("020-10086000");
 log.info("==> JacksonUtil.toJsonString(bean): {}", JacksonUtil.toJsonString(bean));
 String json = JacksonUtil.toJsonString(bean);
 log.info("==> JacksonUtil.toJavaObject: {}", ToStringBuilder.reflectionToString(JacksonUtil.toJavaObject(json, CompanyBean.class)));
 
 }
 2019-01-19 15:42:16.081 [main] INFO com.monbuilder.AppTest - ==> JacksonUtil.toJsonString(bean): {"id":1,"name":"中國移動廣州分公司","address":"廣州市天河區中山大道1號","tel":"020-10086000"}
 2019-01-19 15:42:16.144 [main] INFO com.monbuilder.AppTest - ==> JacksonUtil.toJavaObject: com.monbuilder.bean.CompanyBean@376a0d86[id=1,name=中國移動廣州分公司,address=廣州市天河區中山大道1號,tel=020-10086000]

上面涉及到的示例代碼,皆可以通過打開Github地址[https://github.com/Builder34/toolkit-demo] 獲取。

https://www.toutiao.com/i6648120854502703620/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1548034130&app=news_article&utm_source=weixin&iid=54172054558&utm_medium=toutiao_ios&group_id=6648120854502703620

輪子非常多,當然我們可以重復造輪子,但是我們更提倡的是使用已有優秀的輪子(工具類),開發出更簡潔、優雅、業務邏輯更清晰的代碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM