在现代软件开发中,常常会遇到各种工具类,这些工具类能够极大地提高开发效率和代码的可维护性。本文将介绍几个在Java开发中非常实用的工具类,包括Objects、StringUtils、BeanUtils、ReflectionUtils、DigestUtils和HttpStatus。这些工具类涵盖了从对象操作、字符串处理到数据加密和HTTP状态码的管理,帮助开发者简化复杂的编程任务。
通过这些工具类的使用,开发者不仅能够减少代码量,还能够提高代码的可读性和可复用性。接下来,我们将逐一探讨每个工具类的关键方法及其应用场景,带你深入理解如何在日常开发中利用这些工具来提升工作效率。
今天,我决定与大家分享一些我常用的小工具,希望对你们有所帮助。
本文将分享9个在日常工作中必定会用到的小工具,主要内容如下:
图片
1. Collections
首先介绍的是java.util包下的Collections类。该类主要用于对集合进行操作或返回集合。我个人非常喜欢使用它。以下是一些常用的功能:
1.1 排序
在工作中,常常需要对集合进行排序。我们来看一下如何使用Collections工具实现升序和降序:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
Collections.sort(list); // ASC
System.out.println(list);
Collections.reverse(list); // DESC
System.out.println(list);
输出:
[1, 2, 3]
[3, 2, 1]
1.2 获取最大值或最小值
有时需要在集合中找到最大值或最小值。此时可以使用Collections的max和min方法。
例如:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
Integer max = Collections.max(list);
Integer min = Collections.min(list);
System.out.println(max);
System.out.println(min);
输出:
3
1
1.3 返回空集合
有时在检查空值后,我们需要返回一个空集合。可以使用emptyList方法。例如:
private List<Integer> fun(List<Integer> list) {
if (list == null || list.size() == 0) {
return Collections.emptyList();
}
// ...
return list;
}
1.4 转换为不可修改集合
为了防止后续程序修改某个集合的结果,有时需要将某个集合定义为不可修改。这可以通过Collections的unmodifiablexxx方法轻松实现:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
List<Integer> integers = Collections.unmodifiableList(list);
integers.add(4); // 这里会抛出异常
System.out.println(integers);
输出:
图片
1.5 转换为线程安全集合
我们都知道,Java中的许多集合(如ArrayList、LinkedList、HashMap、HashSet等)都是非线程安全的。
换句话说,在多线程环境中,向这些集合添加数据会导致异常。
此时,可以使用Collections的synchronizedxxx方法直接将这些线程不安全的集合转换为线程安全的集合。例如:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
List<Integer> integers = Collections.synchronizedList(list); // 将ArrayList转换为线程安全集合
System.out.println(integers);
其底层实现会创建SynchronizedRandomAccessList或SynchronizedList类。这两个类的许多方法会使用synchronized进行锁定。
当然,Collections工具类中还有很多常用方法,这里不逐一介绍,大家可以自行探索。
图片
2. CollectionUtils
对于集合操作,除了前面提到的Collections工具类,CollectionUtils工具类也非常常用。
目前,比较主流的有apache中的org.apache.commons.collections包下的CollectionUtils工具类。
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
它提供了许多方法。例如:
图片
当然,Spring框架中也有org.springframework.util包下的CollectionUtils工具类。
不过,我个人推荐使用apache包下的CollectionUtils工具类,因为它有更多更全面的工具。例如,Spring中的CollectionUtils没有判断集合是否非空的方法,而apache中的CollectionUtils就有。
接下来,我们将以apache中的CollectionUtils工具类为例,介绍一些常用的方法。
2.1 检查集合是否为空
CollectionUtils工具类的isEmpty方法可以轻松判断集合是否为空,isNotEmpty方法判断集合是否非空。
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
if (CollectionUtils.isEmpty(list)) {
System.out.println("集合为空。");
}
if (CollectionUtils.isNotEmpty(list)) {
System.out.println("集合非空");
}
2.2 对两个集合进行操作
有时我们需要对两个现有集合进行操作,例如取交集或并集。
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(3);
List<Integer> list2 = new ArrayList<>();
list2.add(2);
list2.add(4);
// 获取并集
Collection<Integer> unionList = CollectionUtils.union(list, list2);
System.out.println(unionList);
// 获取交集
Collection<Integer> intersectionList = CollectionUtils.intersection(list, list2);
System.out.println(intersectionList);
// 获取对称差
Collection<Integer> disjunctionList = CollectionUtils.disjunction(list, list2);
System.out.println(disjunctionList);
// 获取差集
Collection<Integer> subtractList = CollectionUtils.subtract(list, list2);
System.out.println(subtractList);
执行结果:
[1, 2, 3, 4]
[2]
[1, 3, 4]
[1, 3]
对两个集合的操作在实际工作中非常常见。但当你想到某种操作时,可以先检查是否有现成的工具,以避免浪费时间。一般来说,一些基本功能已经实现。
3. Lists
如果你引入了com.google.guava的依赖,你会获得许多有用的小工具。这里推荐一个位于com.google.common.collect包下的集合工具:Lists。
它非常实用,让我爱不释手。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
3.1 快速初始化集合
有时,我们想在集合中初始化一些元素。这时可以使用Lists的newArrayList方法。例如:
List<Integer> list = Lists.newArrayList(1, 2, 3);
这比直接创建一个列表后再一个个添加元素方便得多。
执行结果:
[1, 2, 3]
3.2 笛卡尔积
如果你想对两个集合执行笛卡尔积,Lists的cartesianProduct方法可以帮助你实现:
List<Integer> list1 = Lists.newArrayList(1, 2, 3);
List<Integer> list2 = Lists.newArrayList(4, 5);
List<List<Integer>> productList = Lists.cartesianProduct(list1, list2);
System.out.println(productList);
执行结果:
[[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
3.3 拆分集合(分页)
如果你想将一个大集合拆分成若干个小集合,可以使用Lists的partition方法:
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
List<List<Integer>> partitionList = Lists.partition(list, 2);
System.out.println(partitionList);
执行结果:
[[1, 2], [3, 4], [5]]
在这个例子中,列表有5个数据。我将列表集合拆分成3页,每页大小为2,也就是变成了3个小集合。
这是我最喜欢的方法之一,常在项目中使用。
例如,有一个需求:现在有10,000个id,需要调用批量用户查询接口来获取用户数据。但是如果直接查询10,000个用户,单个接口的响应时间可能会非常慢。
如果改为批量处理,每次只查询500个用户,异步调用20次,就不会出现单个接口响应慢的问题。
3.4 流处理
如果我们想将某个集合转换为另一个接口,可以使用Lists的transform方法。例如:
List<String> list = Lists.newArrayList("a","b","c");
List<String> transformList = Lists.transform(list, x -> x.toUpperCase());
System.out.println(transformList);
小写字母被转换为大写字母。
[A, B, C]
3.5 反转顺序
Lists提供了一个reverse()方法用于反转顺序。例如:
List<Integer> list = Lists.newArrayList(3, 1, 2, 5, 4);
List<Integer> reverseList = Lists.reverse(list);
System.out.println(reverseList);
执行结果:
[4, 5, 2, 1, 3]
当然,Lists还有其他有用的工具。我这里只展示了一些例子,有兴趣的朋友可以深入研究。
图片
4. Objects
在jdk7之后,提供了Objects工具类,我们可以通过它对对象进行操作。
4.1 检查对象是否为null
在Java中,一切都是对象。检查对象是否为null可以说是无处不在。Objects的isNull方法用于检查对象是否为null,而nonNull方法用于检查对象是否不为null。例如:
Integer i = new Integer(10);
if (Objects.isNull(i)) {
System.out.println("对象为null");
}
if (Objects.nonNull(i)) {
System.out.println("对象不为null");
}
4.2 当对象为null时抛出异常
如果我们想在对象为null时抛出空指针异常,可以使用Objects的requireNonNull方法。例如:
Integer i = new Integer(128);
Objects.requireNonNull(i);
Objects.requireNonNull(i, "参数不能为空");
Objects.requireNonNull(i, () -> "参数不能为空");
4.3 检查两个对象是否相等
我们经常需要检查两个对象是否相等。Objects为我们提供了equals方法,可以非常方便地实现:
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(Objects.equals(i1, i2));
执行结果:
true
但在使用这个方法时有一个坑。例如,如果将例子改为:
Integer i = new Integer(1);
Long l = new Long(1);
System.out.println(Objects.equals(i, l));
执行结果:
false
你知道为什么输出false吗?可以在评论区交流。
4.4 获取对象的hashCode
如果你想获取某个对象的hashCode,可以使用Objects的hashCode方法。例如:
String str = new String("abc");
System.out.println(Objects.hashCode(str));
执行结果:
96354
关于Objects的内容介绍到此为止。有兴趣的朋友可以查看下面更多的方法。
图片
5. StringUtils
字符串在我们的日常工作中使用得非常频繁。
在我们的代码中,我们常常需要检查字符串是否为null、转换大小写、拆分字符串、比较字符串、去除多余空格、连接字符串、使用正则表达式等等。
如果我们只使用String类提供的方法,就需要手动写大量的额外代码,这样既耗时又费力。
作为程序员,当然需要学会懒惰 😊。现在有一个现成的工具类,org.apache.commons.lang3包下的StringUtils工具类,为我们提供了非常丰富的选择。
5.1 检查字符串是否为null
实际上,对于一个空字符串,不仅有null,还有""、" "、"null",以及许多其他情况。
StringUtils为我们提供了多个静态方法来检查字符串是否为null。例如:
String str1 = null;
String str2 = "";
String str3 = " ";
String str4 = "abc";
System.out.println(StringUtils.isEmpty(str1));
System.out.println(StringUtils.isEmpty(str2));
System.out.println(StringUtils.isEmpty(str3));
System.out.println(StringUtils.isEmpty(str4));
System.out.println("-------------------------------------");
System.out.println(StringUtils.isNotEmpty(str1));
System.out.println(StringUtils.isNotEmpty(str2));
System.out.println(StringUtils.isNotEmpty(str3));
System.out.println(StringUtils.isNotEmpty(str4));
System.out.println("-------------------------------------");
System.out.println(StringUtils.isBlank(str1));
System.out.println(StringUtils.isBlank(str2));
System.out.println(StringUtils.isBlank(str3));
System.out.println(StringUtils.isBlank(str4));
System.out.println("-------------------------------------");
System.out.println(StringUtils.isNotBlank(str1));
System.out.println(StringUtils.isNotBlank(str2));
System.out.println(StringUtils.isNotBlank(str3));
System.out.println(StringUtils.isNotBlank(str4));
输出:
true
true
false
false
-------------------------------------
false
false
true
true
-------------------------------------
true
true
true
false
-------------------------------------
false
false
false
true
示例中的四个null检查方法:isEmpty、isNotEmpty、isBlank和isNotBlank。可以根据实际情况使用这些方法。
建议优先使用 *isBlank* 和*isNotBlank* 方法,因为它们也会考虑到 *" "* 的情况。
5.2 拆分字符串
拆分字符串是一个常见需求。如果你直接使用String类的split方法,可能会出现空指针异常。
String str1 = null;
System.out.println(StringUtils.split(str1, ","));
System.out.println(str1.split(","));
输出:
图片
使用StringUtils的split方法会返回null,而使用String的split方法则会报指针异常。
5.3 检查是否为纯数字
给定一个字符串,检查它是否为纯数字,可以使用isNumeric方法。例如:
String str1 = "123";
String str2 = "123abc";
String str3 = "0.33";
System.out.println(StringUtils.isNumeric(str1));
System.out.println(StringUtils.isNumeric(str2));
System.out.println(StringUtils.isNumeric(str3));
输出:
true
false
false
5.4 将集合连接成字符串
有时,我们需要将集合的内容连接成一个字符串,然后输出。这时可以使用join方法。例如:
List<String> list = Lists.newArrayList("a", "b", "c");
List<Integer> list2 = Lists.newArrayList(1, 2, 3);
System.out.println(StringUtils.join(list, ","));
System.out.println(StringUtils.join(list2, " "));
输出:
a,b,c
1 2 3
当然,还有许多实用方法。我不会在这里一一介绍。
6. BeanUtils
Spring为我们提供了一个用于JavaBean的工具类,位于org.springframework.beans包下。它的名字是:BeanUtils。
让我们看看这个工具能给我们带来什么惊喜。
6.1 复制对象属性
你是否遇到过这样的需求:将某个对象的所有属性复制到另一个对象中。这个时候,可以使用BeanUtils的copyProperties方法。例如:
User user1 = new User();
user1.setId(1L);
user1.setName("Dylan");
user1.setAddress("香港");
User user2 = new User();
BeanUtils.copyProperties(user1, user2);
System.out.println(user2);
6.2 获取指定类的指定方法
如果你想获取某个类的指定方法以便后续操作,可以使用BeanUtils的findDeclaredMethod方法。例如:
Method declaredMethod = BeanUtils.findDeclaredMethod(User.class, "getId");
System.out.println(declaredMethod.getName());
6.3 获取指定方法的参数
如果你想获取某个方法的参数,可以使用BeanUtils的findPropertyForMethod方法。例如:
Method declaredMethod = BeanUtils.findDeclaredMethod(User.class, "getId");
PropertyDescriptor propertyForMethod = BeanUtils.findPropertyForMethod(declaredMethod);
System.out.println(propertyForMethod.getName());
如果你对BeanUtils感兴趣,可以看看以下内容:
7. ReflectionUtils
有时,我们需要在项目中使用reflection功能。如果我们使用最原始的方法开发,代码量会非常大,且麻烦。需要处理大量的异常和访问权限问题。
好消息是,Spring为我们提供了一个ReflectionUtils工具类,位于org.springframework.util包下。
7.1 获取方法
如果你想获取某个类的某个方法,可以使用ReflectionUtils类的findMethod方法。例如:
Method method = ReflectionUtils.findMethod(User.class, "getId");
7.2 获取字段
如果你想获取某个类的某个字段,可以使用ReflectionUtils类的findField方法。例如:
Field field = ReflectionUtils.findField(User.class, "id");
7.3 执行方法
如果你想通过反射调用某个方法并传递参数,可以使用ReflectionUtils类的invokeMethod方法。例如:
ReflectionUtils.invokeMethod(method, springContextsUtil.getBean(beanName), param);
7.4 检查字段是否为常量
如果你想检查一个字段是否为常量,可以使用ReflectionUtils类的isPublicStaticFinal方法。例如:
Field field = ReflectionUtils.findField(User.class, "id");
System.out.println(ReflectionUtils.isPublicStaticFinal(field));
7.5 检查是否为equals方法
如果你想检查某个方法是否为equals方法,可以使用ReflectionUtils类的isEqualsMethod方法。例如:
Method method = ReflectionUtils.findMethod(User.class, "getId");
System.out.println(ReflectionUtils.isEqualsMethod(method));
当然,这个类还有许多有趣的方法。有兴趣的朋友可以点击进入这个类自行查看。
图片
8. DigestUtils
有时,我们需要对数据进行加密,例如使用md5或sha256。
我们可以使用Apache的org.apache.commons.codec.digest包下的DigestUtils类。
8.1 MD5加密
如果你想使用MD5加密数据,可以使用DigestUtils的md5Hex方法。例如:
String md5Hex = DigestUtils.md5Hex("Dylan");
System.out.println(md5Hex);
8.2 SHA256加密
如果你想使用SHA256加密数据,可以使用DigestUtils的sha256Hex方法。例如:
String sha256Hex = DigestUtils.sha256Hex("Dylan");
System.out.println(sha256Hex);
当然,这个工具还有许多其他加密方法:
图片
9. HttpStatus
很多时候,我们会在代码中定义HTTP返回代码。例如,正常接口返回200,异常返回500,如果接口找不到,则返回404。
private int SUCCESS_CODE = 200;
private int ERROR_CODE = 500;
private int NOT_FOUND_CODE = 404;
实际上,org.springframework.http包下的HttpStatus枚举或org.apache.http包下的HttpStatus接口已经为我们定义了常用的HTTP返回代码。我们可以直接使用它们,确实不需要重新定义。
图片
结论
在本篇文章中,我们深入探讨了多个实用的Java工具类,展示了如何利用这些类来简化编程工作。无论是通过Objects来进行对象的检查与操作,还是使用StringUtils进行字符串的处理,抑或是借助BeanUtils与ReflectionUtils进行对象属性的复制和反射操作,这些工具类都为我们提供了强大的支持。此外,DigestUtils则让数据加密变得简单高效,而HttpStatus则帮助我们规范HTTP响应码的使用。
掌握这些工具类的使用,不仅可以提升开发效率,还能减少潜在的错误,使代码更加简洁和易于维护。在今后的开发实践中,希望读者能够充分利用这些工具,提升自己的编程技能,写出更加高质量的代码。欢迎大家探索更多的Java工具类,进一步增强你的开发能力。