为什么要使用工具类库?

逻辑完备

List<String> list = ...;
if(list.isEmpty()){
  //略
}

if(CollectionUtils.isEmpty(list)){
   // 略
}

代码简洁

String str = ....;
if(str != null && str.trim().length != 0){
   // 略
}
if(bean.getName()!=null){
   bean.setName("default");
}
bean.setName(StringUtils.defaultString(bean.getName(),"default"));

if(StringUtils.isNotBlank(str)){
   // 略
}

功能统一

String str = ...;
if(str!=null){...}
if(str!=null && str!=""){...}
if(str!=null && str.trim().length!=0){...}

if(StringUtils.isNotBlank(str)){...}

性能更好

涉及一些复杂操作时,工具类的性能一般会更好。

Arrays.sort()

commons.lang

commons.lang是apache提供的一个Java工具类库。官网参见:apache commons。从2.6版本以后,包名更新为commons.lang3。目前正式版版本是3.8.1:

<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.8.1</version>
</dependency>

根据javadoc,commons.lang提供的工具包有:

PACKAGEDESCRIPTION
org.apache.commons.lang3Provides highly reusable static utility methods, chiefly concerned with adding value to the java.lang classes.
org.apache.commons.lang3.archProvides classes to work with the values of the os.arch system property.
org.apache.commons.lang3.builderAssists in creating consistent equals(Object), toString(), hashCode(), and compareTo(Object) methods.
org.apache.commons.lang3.concurrentProvides support classes for multi-threaded programming.
org.apache.commons.lang3.eventProvides some useful event-based utilities.
org.apache.commons.lang3.exceptionProvides functionality for Exceptions.
org.apache.commons.lang3.mathExtends java.math for business mathematical classes.
org.apache.commons.lang3.mutableProvides typed mutable wrappers to primitive values and Object.
org.apache.commons.lang3.reflectAccumulates common high-level uses of the java.lang.reflect APIs.
org.apache.commons.lang3.textProvides classes for handling and manipulating text, partly as an extension to java.text.
org.apache.commons.lang3.text.translateAn API for creating text translation routines from a set of smaller building blocks.
org.apache.commons.lang3.timeProvides classes and methods to work with dates and durations.
org.apache.commons.lang3.tupleTuple classes, starting with a Pair class in version 3.0.

我们来看一些比较常用的工具类。

ArrayUtils

它的javadoc如下:

Operations on arrays, primitive arrays (like int[]) and primitive wrapper arrays (like Integer[]).
This class tries to handle null input gracefully. An exception will not be thrown for a null array input. However, an Object array that contains a null element may throw an exception. Each method documents its behaviour.
#ThreadSafe#

从中可知:

  • ArrayUtils可以处理普通的数组、基本类型数组和包装类型数组。
  • ArrayUtils可以“优雅”地处理数组本身为null的情况,不会抛出异常。但是,对数据元素为null的情况,则有可能抛出异常,视各方法而定。
  • ArrayUtils线程安全。

然后我们来看一些常用方法。

toString()

这里的toString不是ArrayUtils自己的toString,而是对指定数组进行toString。

默认情况下,一个数组的toString()只会按“类名@内存地址”格式进行输出,而不会输出数组中的元素。这种默认格式对我们记录日志毫无用处。另外,如果我们显式调用了数组.toString()方法,那么当数组本身为null时,就会抛出NPE。

ArrayUtils类提供了两个toString()方法:

public static String toString(final Object array)

public static String toString(final Object array, final String stringIfNull)

一般我们都使用第一个方法,参见UtilTest#testArrayUtilsToString()

需要注意一点:ArrayUtils.toString()方法依赖于数组内元素的toString()方法。

BooleanUtils

它的javadoc如下:

Operations on boolean primitives and Boolean objects.
This class tries to handle null input gracefully. An exception will not be thrown for a null input. Each method documents its behaviour in more detail.
#ThreadSafe#

BooleanUtils提供了很多布尔运算的方法,例如基本的and/or/not/xor等。此外还提供了一些int/String类型转布尔的方法,如:

public static boolean toBoolean(final int value);

public static boolean toBoolean(final int value, final int trueValue, final int falseValue);

public static boolean toBoolean(final String str);

public static boolean toBoolean(final String str, final String trueString, final String falseString);

具体用法参见各方法的javadoc,或参考UtilTest#testBooleanUtils()

RandomUtils和RandomStringUtils

封装了Java随机数生成器和随机字符串生成器。

RandomUtils可以比Random类更简单地生成随机地生成各种类型的随机数;RandomStringUtils则提供了一个比UUID更简单高效的随机字符串生成器。但是RandomStringUtils并不能保证严格的、全局的唯一性。在不要求严格唯一的情况下可以使用它。

参考UtilTest#testRandomStringUtils()

StringUtils

这大概是最常用的类。这个类提供了一系列的null安全的方法,例如:

  • IsEmpty/IsBlank - checks if a String contains text
  • Trim/Strip - removes leading and trailing whitespace
  • Equals/Compare - compares two strings null-safe
  • startsWith - check if a String starts with a prefix null-safe
  • endsWith - check if a String ends with a suffix null-safe
  • IndexOf/LastIndexOf/Contains - null-safe index-of checks
  • IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut - index-of any of a set of Strings
  • ContainsOnly/ContainsNone/ContainsAny - does String contains only/none/any of these characters
  • Substring/Left/Right/Mid - null-safe substring extractions
  • SubstringBefore/SubstringAfter/SubstringBetween - substring extraction relative to other strings
  • Split/Join - splits a String into an array of substrings and vice versa
  • Remove/Delete - removes part of a String
  • Replace/Overlay - Searches a String and replaces one String with another
  • Chomp/Chop - removes the last part of a String
  • AppendIfMissing - appends a suffix to the end of the String if not present
  • PrependIfMissing - prepends a prefix to the start of the String if not present
  • LeftPad/RightPad/Center/Repeat - pads a String
  • UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize - changes the case of a String
  • CountMatches - counts the number of occurrences of one String in another
  • IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable - checks the characters in a String
  • DefaultString - protects against a null input String
  • Rotate - rotate (circular shift) a String
  • Reverse/ReverseDelimited - reverses a String
  • Abbreviate - abbreviates a string using ellipsis or another given String
  • Difference - compares Strings and reports on their differences
  • LevenshteinDistance - the number of changes needed to change one String into another

参考UtilTest#testStringUtils()

NumberUtils

修改魔法值时,我们声明了一大堆的0/1这种数字。实际上,在这个类里就已经提供了很多这类常量了。

MODIFIER AND TYPEFIELD AND DESCRIPTION
static ByteBYTE_MINUS_ONE Reusable Byte constant for minus one.
static ByteBYTE_ONE Reusable Byte constant for one.
static ByteBYTE_ZERO Reusable Byte constant for zero.
static DoubleDOUBLE_MINUS_ONE Reusable Double constant for minus one.
static DoubleDOUBLE_ONE Reusable Double constant for one.
static DoubleDOUBLE_ZERO Reusable Double constant for zero.
static FloatFLOAT_MINUS_ONE Reusable Float constant for minus one.
static FloatFLOAT_ONE Reusable Float constant for one.
static FloatFLOAT_ZERO Reusable Float constant for zero.
static IntegerINTEGER_MINUS_ONE Reusable Integer constant for minus one.
static IntegerINTEGER_ONE Reusable Integer constant for one.
static IntegerINTEGER_TWO Reusable Integer constant for two.
static IntegerINTEGER_ZERO Reusable Integer constant for zero.
static LongLONG_MINUS_ONE Reusable Long constant for minus one.
static LongLONG_ONE Reusable Long constant for one.
static LongLONG_ZERO Reusable Long constant for zero.
static ShortSHORT_MINUS_ONE Reusable Short constant for minus one.
static ShortSHORT_ONE Reusable Short constant for one.
static ShortSHORT_ZERO Reusable Short constant for zero.

DateFormatUtils

日期格式化是常见的一种操作。大多数时候我们都是直接使用SimpleDateFormatter来做格式化。DateFormatUtils提供了一系列格式化方法。

参考UtilTest#testDateFormatUtils()

DateUtils

除了格式化,日期还有很多操作,如计算两天的差值、加/减一天、抹掉时分秒等。DateUtils提供了一些相关工具方法。

参考UtilTest#testDateUtils()

ReflectionToStringBuilder

这个是一个用来处理toString的类。它可以通过反射把对象中的所有字段都加入到toString()字符串中。因为是反射操作,所以当我们修改对象字段(新增/删除/改名)时,不需要再费心去修改toString()方法。

此外,配合ToStringStyle类,我们可以控制toString()的输出样式。标准样式是“类全名@内存地址[字段名=字段值,字段名=字段值]”这样的:

com.yirendai.lab.athenschool.util.TestBean@156643d4[age=1,name=Ikari]

如果使用Json格式(ToStringStyle.JSON_STYLE),则会完全按JSON格式输出:

{"age":1,"name":"Ikari"}

此外还有其它样式,可以自己看看。

此外,还可以通过@ToStringExclude注解来标记哪些字段(例如用户密码)不需要在toString()中输出。

建议的用法是:

@Override
public String toString(){
   return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
}

当然,使用JSON_STYLE还是其它什么style,看个人需求。JSON格式便于格式化,但是在ELK上查找时可能会遇到些问题。

commons.*

commons系列工具类同样是Apache出品,除了上面的commons-lang/lang3之外,还包括有:

  • commons-io
  • commons-logging
  • commons-codec
  • commons-beanutils
  • commons-collections

其中用得比较多有commons-collections和comons-beanutils。

commons-collections4是个集合相关工具类,官网地址是commons-collections。目前版本是4.3。个人用的比较多的只是CollectionUtils#containsAny()/isNotEmpty()和MapUtils中的各种get方法了。其实CollectionUtils里还提供了很多集合运算的方法,如计算并集/判断子集等,只不过咱们用到的集合运算不多。MapUtils里也提供了不可变Map的构造方法,但是后来就改用guava的了。

comons-beanutils是反射相关工具类,官网地址是commons-beanutils。目前版本是1.9.3。它提供了一系列简单易用的反射相关工具。个人用得比较多的是BeanUtils#copyProperties()方法。但是这个方法还是有点问题:会抛出异常,并且要求有getter/setter方法。

guava-libraries

guava是Google提供的一个工具包,目前版本是27.0.1,分jre和Android两个包。可以参考:Git-Hub:google/guava、Google Guava官方教程(中文版)等。这里面的包我用得不多…… netty