当前位置: 首页 > 编程日记 > 正文

推荐使用的几款Java常用基础工具库

通用工具类(字符串、时间格式化、BeanUtils、IO)

1. commons-lang3库

1.1. org.apache.commons.lang3.StringUtils类

日常代码中,我们经常和String字符串打交道,经常对字符串进行处理,稍微不注意的话,很容易出现类似NullPointerException这种简单的错误,我们经常写各种if来判断处理这些非业务的逻辑。这时,我们可以利用大牛apache的轮子,通过其StringUtils里面的一些常用方法,改善我们的代码,让我们的业务代码更简洁、优雅。示例代码:

  @Slf4jpublic class AppTest {@Testpublic 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

时间转换工具类:

      @Testpublic 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类

      @Testpublic 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)映射成beanBeanUtils.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转换成MapMap 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后,我们的处理代码或简洁非常多的。

      @Testpublic 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): 可关闭流\Socket\SocketServer等多种对象

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* */@Slf4jpublic 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 "{}";}}复制代码

运用上面的工具类,示例:

    @Testpublic 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] 获取,或者点击阅读原文,跳转到代码库连接。

最后想要说的是,轮子非常多,当然我们可以重复造轮子,但是我们更提倡的是使用已有优秀的轮子(工具类),开发出更简洁、优雅、业务逻辑更清晰的代码。


                                                           -END-




扫描微信公众号关注一下,互相交流学习哟


转载于:https://juejin.im/post/5c43cc3bf265da6169178213

相关文章:

ARKit 与 ARCore比对(三)

ARKit 和 ARCore剖析、结构、原理介绍 ARKit 和 ARCore 都是三部分&#xff1a;相机姿态估计&#xff0c; 环境感知&#xff08;平面估计&#xff09;及光源感知。 ARCore 的部分源码&#xff1a;https://github.com/google-ar/arcore-unity-sdk/tree/master/Assets/GoogleARCo…

前端开发之retina屏幕

像素 && ppi 首先先说一下pixel(picture element)&#xff0c;显示图像的最小单位&#xff0c;有多个带色彩的像素点组成的整体就是一张图像。然后再说一下ppi(pixel per inch)这个概念&#xff0c;其实就是在每英寸显示的像素数。 设备像素 && 逻辑像素 &…

【ACM】Uva 1152 (4 Values whose Sum is 0) 二分查找lower_bound() 和upper_bound()的使用

【问题描述】 The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d) ∈ A B C D are such that a b c d 0. In the following, we assume that all lists have the same size n. …

广东“基因编辑婴儿事件”调查组:将对贺建奎依法依规严肃处理

雷锋网(公众号&#xff1a;雷锋网)消息&#xff0c;1 月 21 日&#xff0c;新华社报道了关于“基因编辑婴儿事件”的初步调查结果&#xff0c;该结果宣称&#xff0c;该事件是南方科技大学副教授为了追逐个人名利而进行的人类胚胎基因编辑活动&#xff1b;而在此过程中&#xf…

测试我的第一个随笔

# encodingutf-8## Python Version 3.5# 利用数学中的复数 求解 一元一次方程(从网上看来的)def solve(qx, var): qx qx.replace(, -() ) c eval(qx , {var: 1j}) return -c.real/c.imagres solve(2*x 4 8,x)print(res)转载于:https://www.cnblogs.com/imyjy/p/…

ubuntu16.04 下安装Opencv2.4.9

ubuntu16.04 下安装Opencv2.4.9 OpenCV的源码download from: https://sourceforge.net/projects/opencvlibrary/?sourcetyp_redirect[plain] view plaincopycd opencv-2.4.9 mkdir build sudo chmod -R 777 build cd build [plain] view plaincopycmake -D CMAKE_…

UVa 167(八皇后)、POJ2258 The Settlers of Catan——记两个简单回溯搜索

UVa 167 题意&#xff1a;八行八列的棋盘每行每列都要有一个皇后&#xff0c;每个对角线上最多放一个皇后&#xff0c;让你放八个&#xff0c;使摆放位置上的数字加起来最大。 参考&#xff1a;https://blog.csdn.net/xiaoxiede_wo/article/details/79973171 1 #include <io…

AR + ROS +UBUNTU16.04+ORB-SLAM2

ORB SLAM2 USB摄像头 实验环境ubuntu 16.04ros kinetic OPencv2.4.9 Step1&#xff1a; 配置环境变量 $ mkdir -p ~/catkin_ws/src $ cd ~/catkin_ws/src 在’src’目录中可能没有任何软件包&#xff0c;只有一个CMakeLists.txt&#xff0c;依然可以编译它&#xff1a; …

Cross-validation

2019独角兽企业重金招聘Python工程师标准>>> 1: Introduction To Validation So far, weve been evaluating accuracy of trained models on the data the model was trained on. While this is an essential first step, this doesnt tell us much about how well …

【ACM】杭电OJ 1877 又一版A+B(进制转换)

注意&#xff1a;A和B都是0的情况 A和B为int也可以AC #include<cstdio> #include <iostream> using namespace std;const int maxn 10000;int a[maxn];int main() {long long A,B;int m,k;while(scanf("%d",&m)!EOF){if(m0) return 0;scanf("…

[POI2009]KAM-Pebbles BZOJ1115 [ 待填坑 ] 博弈

有N堆石子&#xff0c;除了第一堆外&#xff0c;每堆石子个数都不少于前一堆的石子个数。两人轮流操作每次操作可以从一堆石子中移走任意多石子&#xff0c;但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏。问先手是否必胜。 感谢MT大牛翻译. Sample OutputNIE…

ROS中使用摄像头的问题

ROS中使用摄像头的问题 0.prepare 4 . 安装uvc_cam $ sudo apt-get install ros-indigo-uvc-camera $ source /opt/ros/indigo/setup.bash 采用apt-get的方式&#xff0c;直接装在了ROS的安装路径中&#xff0c;并设置工作路径。 安装成功后在/opt/ros/hydro/的路径中就…

EmEditor Professional(文本编辑) 下载地址

http://www.greenxf.com/soft/2126.html 16.1.5 http://www.cr173.com/soft/3031.html 16.3.0 http://www.pc6.com/softview/SoftView_43146.html 17.8.1 绿色注册版 EmEditor 71 个实用插件汉化版 http://www.onlinedown.net/soft/35609.htm

【ACM】杭电OJ 4548 美素数(二次打表)

二次打表&#xff0c;第一次是标记哪些是素数&#xff0c;哪些不是。 第二次是前n个数中 “本身是素数 && 各个位上的和是素数 ” 的个数 TLE&#xff1a; #include <iostream> #include <cstdio> using namespace std;int fun1(int x) {int sum0…

animation与transition区别

transition&#xff1a; 过渡属性 过渡所需要时间 过渡动画函数 过渡延迟时间&#xff1b;默认值分别为&#xff1a;all 0 ease 0 1、局限性&#xff1a; 1&#xff09;只能设置一个属性 2&#xff09;需要伪类/事件触发才执行 3&#xff09;只能设置动画初始值和结束值 2、过…

如何将cocos2d-x程序分别移植到ios,android,windowsphone三个手机平台上

作者&#xff1a;方格子链接&#xff1a;https://www.zhihu.com/question/21505500/answer/22152464来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。面向android的移植 0. 这移植过程简直…… 1. 完成以上工具的下载安装…

【数据结构】顺序循环队列及其实现(C语言)

给定一个大小为MAXSIZE的数组储存一个队列&#xff0c;经过若干次的插入和删除以后&#xff0c;当队尾指针 rear MAXSIZE 时&#xff0c;呈现队列满的状态&#xff0c;而事实上数组的前部可能还有空闲的位置。为了有效地利用空间&#xff0c;引入循环队列&#xff08;环状&…

C++中Reference与指针(Pointer)的使用对比

了解引用reference与指针pointer到底有什么不同可以帮助你决定什么时候该用reference&#xff0c;什么时候该用pointer。在C 中&#xff0c;reference在很多方面与指针(pointer)具有同样的能力。虽然多数C程序员对于何时使用reference何时使用pointer 都会有一些直觉&#xff0…

云南实现手机自主补(换)领居民身份证

图为云南首位通过手机自主补领居民身份证的申领人付宏强。 缪超 摄 中新网昆明1月22日电 (缪超)春节临近&#xff0c;云南实现手机自主补(换)领居民身份证&#xff0c;首张通过手机补办的居民身份证于22日在武定县公安局狮山派出所成功申领。 据悉&#xff0c;为方便民众因遗失…

NDK JNI 安装与配置(一)(UBUNTU16.04 )

1、下载Android NDK自解压包&#xff0c;官方地址&#xff1a;https://developer.android.com/ndk/downloads/index.html#download下载&#xff1a;$ wget -c http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin2、解压&#xff0c;将Android NDK压缩包解压到…

【数据结构】顺序表的应用(4)(C语言)

【数据结构】顺序表的应用&#xff08;1&#xff09;&#xff08;C语言&#xff09; 【数据结构】顺序表的应用&#xff08;2&#xff09;&#xff08;C语言&#xff09; 【数据结构】顺序表的应用&#xff08;3&#xff09;&#xff08;C语言&#xff09; 设计一个算法&…

Java泛型:泛型类、泛型接口和泛型方法

2019独角兽企业重金招聘Python工程师标准>>> 根据《Java编程思想 &#xff08;第4版&#xff09;》中的描述&#xff0c;泛型出现的动机在于&#xff1a;有许多原因促成了泛型的出现&#xff0c;而最引人注意的一个原因&#xff0c;就是为了创建容器类。 泛型类 容器…

POJ 2456 Aggressive cows(二分答案)

Aggressive cowsTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 22674 Accepted: 10636Description Farmer John has built a new long barn, with N (2 < N < 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0…

JMeter打开脚本报错处理方法

今天电脑重装了系统&#xff0c;安装好jmeter后打开以前写的脚本&#xff0c;总是报错如下图&#xff0c;研究了半天也没搞明白。 后来一个群里的人员提醒才想起来&#xff0c;是脚本的问题&#xff0c;为啥捏&#xff1f; 因为之前写的脚本用了一些监听&#xff0c;而这些监听…

Android开发中libs包下面的mips、armeabi、armeabi-v7a和x86

简介 在Android日常的开发过程中有的项目需要引入第三方的库&#xff0c;有时候大家可能会在libs文件夹下看到 mips、armeabi、armeabi-v7a和x86这四个文件夹。那么这三个文件夹下面的包是干什么用的&#xff1f; 这三个包下面存放的用C编译的本地库文件&#xff08;各类『.…

【数据结构】判断一个单链表中各结点的值是否有序

count记录的是单链表的总长 count1记录的是升序的结点的个数 count2记录的是降序的结点的个数 如果count1或者count2等于count&#xff0c;那么就说明该序列是升序或者降序的。 稍加改进可以在准确判断是升序还是降序还是无序 &#xff08;个人认为链表中只有一个结点或者…

MSSQL-最佳实践-行级别安全解决方案

title: MSSQL-最佳实践-行级别安全解决方案 author: 风移 摘要 在SQL Server安全系列专题月报分享中&#xff0c;我们已经分享了&#xff1a;如何使用对称密钥实现SQL Server列加密技术、使用非对称密钥加密方式实现SQL Server列加密、使用混合密钥实现SQL Server列加密技术和列…

浮点数运算原理详解

导读&#xff1a; 浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。 许多人使用float/double进行货币计算时经常会犯错。这篇文章是这一系列中的精华&#xff0c;所有的软件开发人员都…

vCenter的安装

转载于:https://blog.51cto.com/yht1990/1857211

【数据结构】双链表的应用

1、设计一个算法&#xff0c;在双链表中值为y的结点前面插入一个值为x的新结点&#xff0c;即使得值为x的新结点成为值为y的结点的前驱结点。 2、设计一个算法&#xff0c;将一个双链表改建成一个循环双链表。 #include <stdio.h> #include <stdlib.h>typedef st…