持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情。
学习使用常用工具类。
java常用工具类
熟练使用工具类,避免重复造轮子
Collections
java.util包下的`Collections类,该类主要用于操作集合。和Collection接口不同,Collections类一般用来操作实现Collection接口的类。
排序
Collections类提供了对List<>集合进行排序的api。
- 可自定义比较器Comparator。默认升序排序
- reverse会将集合倒置,配合升序排序,可以实现降序排序
底层使用的
Arrays.sort(a, (Comparator) c)方法
/**
* 生成10个随机数在 start到end之前的数字
*
* @param count
* @param start
* @param end
* @return
*/
public List<Integer> createRandomCollection(int count, int start, int end) {
//检查count大于0
Assert.check(count > 0);
List<Integer> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
list.add((int) (Math.random() * (end - start)) + start);
}
return list;
}
/**
* 使用CollectionS对List进行排序
*/
@Test
public void collectionsSort() {
List<Integer> integerList = createRandomCollection(20, 5, 20);
System.out.println("原集合:=》\n" + integerList);
//升序
Collections.sort(integerList);
System.out.println("降序排序后:=》\n" + integerList);
//可自定义比较器
Collections.sort(integerList, (val1, val2) -> {
if (val1 > val2) {
return -1;
} else {
return 1;
}
});
System.out.println("自定义比较器实现升序:=》\n" + integerList);
//将集合倒过来
final List<Integer> randomCollection = createRandomCollection(20, 5, 20);
System.out.println("愿集合:=》\n"+randomCollection);
Collections.reverse(randomCollection);
System.out.println("倒置后:=》\n"+randomCollection);
}
获取极值
可以使用
Collections获取集合的最大最小值。同样可以自定义比较器。
/**
* 使用Collections获取集合的最大最小值
*/
@Test
public void getMaxAndMin() {
List<Integer> integerList = createRandomCollection(20, 5, 20);
System.out.println("集合:" + integerList);
//最大值
System.out.println("最大值:" + Collections.max(integerList));
//最小值
System.out.println("最小值:" + Collections.min(integerList));
}
转换线程安全集合
java中除了Concurrent包下的集合,其余的大多数是非线程安全的,Collectios提供了可以将非线程安全的集合转化为线程安全的集合。
可以使用synchronizedXXXX方法转化为线程安全的集合,返回的集合类型是Collectios的静态内部类。但是不推荐,因为使用Collections转化的线程安全的集合都是使用Synchronized加锁实现的,性能不乐观。
/**
* 将非线程安全的集合转化为线程安全的集合
*/
@Test
public void toConcurrentList() {
final List<Integer> randomCollection = createRandomCollection(20, 5, 20);
Collection<Integer> integers = Collections.synchronizedCollection(randomCollection);
}
判空后返回空集合而不是null
返回的集合是一个范型,不用手动转换
/**
* 在判空后,需要返回空集合而不是null。可以借助Collections.emptyList()方法
*/
@Test
public void returnEmpty() {
final List<Object> objects = Collections.emptyList();
}
二分查找
/**
* 二分查找。给定集合,返回下标
*/
@Test
public void binarySearch() {
final List<Integer> randomCollection = createRandomCollection(20, 5, 20);
System.out.println(randomCollection);
final int target = Collections.binarySearch(randomCollection, 10);
System.out.println(target);
}
转化为不可修改集合
如果某个流程不希望后续程序修改集合,可以使用此方法返回不可修改集合。
/**
* 转化为不可修改集合
*/
@Test
public void toUnModify() {
final List<Integer> randomCollection = createRandomCollection(20, 5, 20);
final List<Integer> integerList = Collections.unmodifiableList(randomCollection);
integerList.add(1);
}
CollectionUtils
对集合操作,除了
Collections工具类以外,CollectionUtils也很常用。常用的两个分别是
Spring.framework.util和org.apache.commons.collections下的CollectionUtils。两者差不多,但是apache下的工具类功能更全。
我们以Spring框架为我们提供的工具类为例。
引入依赖:引入Spring上下文依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
集合判空
spring为我们提供了isEmpty方法,而apache提供了isEmpty() 和isNotEmpty()方法。
/**
* 集合判空,集合为null,或元素个数为0
*/
@Test
public void testCollectionIsEmpty() {
final List<Integer> randomCollection = createRandomCollection(20, 5, 15);
if (CollectionUtils.isEmpty(randomCollection)) {
System.out.println("集合为空");
}else {
System.out.println("集合不为空");
}
}
集合合并
对两个集合进行合并操作。比如取交集、并集。此方法spring未提供,需要引入apache包依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
/**
* 集合合并
* - 获取并集
* - 获取交集
* - 交集的补集
* - 差集
*/
@Test
public void testCollectionMerge() {
final List<Integer> randomCollection1 = createRandomCollection(5, 0, 9);
final List<Integer> randomCollection2 = createRandomCollection(5, 0, 9);
System.out.println("原集合1+=》\n" + randomCollection1);
System.out.println("原集合2+=》\n" + randomCollection2);
//并集
final Collection<Integer> union = org.apache.commons.collections4.CollectionUtils.union(randomCollection1, randomCollection2);
System.out.println("并集=》\n" + union);
//交集
final Collection<Integer> intersection = org.apache.commons.collections4.CollectionUtils.intersection(randomCollection1, randomCollection2);
System.out.println("交集=》\n" + intersection);
//交集的补集
final Collection<Integer> disjunction = org.apache.commons.collections4.CollectionUtils.disjunction(randomCollection1, randomCollection2);
System.out.println("补集=》\n" + disjunction);
//差集
final Collection<Integer> subtract = org.apache.commons.collections4.CollectionUtils.subtract(randomCollection1, randomCollection2);
System.out.println("差集=》\n" + subtract);
}
Lists
该工具类由Guaua工程提供,由Google工程师开发且广泛使用,使用轮子可以使得我们代码简洁。
依赖:
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
创建空集合
/**
* Lists创建空集合
*/
@Test
public void createEmptyList() {
//空的LinkedList
LinkedList<String> linkedList = Lists.newLinkedList();
//空的ArrayList
ArrayList<String> arrayList = Lists.newArrayList();
//空的copyOnWriteArrayList,arrayList的线程安全版本
CopyOnWriteArrayList<String> copyOnWriteArrayList = Lists.newCopyOnWriteArrayList();
}
快速初始化一个集合
借助可变长参数,快速初始化一个集合
/**
* 可变长参数快速初始化集合
* 可以是可变长参数
* 可以是Iterable
*/
@Test
public void quickInitList() {
ArrayList<Integer> arrayList = Lists.newArrayList(1, 2, 3, 4, 5);
System.out.println(arrayList);
}
笛卡尔积
/**
* 笛卡尔积
* 这是一个可变长参数
*/
@Test
public void cartesianProduct() {
List<Integer> randomCollection1 = CollectionUtilsTest.createRandomCollection(3, 0, 9);
List<Integer> randomCollection2 = CollectionUtilsTest.createRandomCollection(3, 0, 9);
System.out.println(Lists.cartesianProduct(randomCollection1, randomCollection2));
}
集合拆分
将一个大集合拆分为多个小集合,需要指定原集合和拆分后集合的大小
/**
* 拆分
* <p>
* 将一个大集合分割成落干个小集合,只需要制定集合和拆分集合大小即可
*/
@Test
public void splitList() {
List<Integer> randomCollection1 = CollectionUtilsTest.createRandomCollection(10, 0, 9);
System.out.println(randomCollection1);
List<List<Integer>> lists = Lists.partition(randomCollection1, 3);
System.out.println("拆分后:");
for (List<Integer> list : lists) {
System.out.println(list);
}
}
以流的形式转化
以流的形式将一个集合转化成另一个集合。以二进制流的形式转换,比循环处理效率高多了。
/**
* 以流的形式讲一个集合转化成另一个集合
*/
@Test
public void transForm() {
List<Integer> randomCollection1 = CollectionUtilsTest.createRandomCollection(10, 0, 9);
final List<Integer> transform = Lists.transform(randomCollection1, element -> --element);
System.out.println(randomCollection1);
System.out.println(transform);
System.out.println("当然Collection接口也提供了");
List<Integer> collect = randomCollection1.stream().map(element -> --element).collect(Collectors.toList());
System.out.println(collect);
}
颠倒集合
/**
* 将集合颠倒
*/
@Test
public void reverse() {
List<Integer> randomCollection1 = CollectionUtilsTest.createRandomCollection(10, 0, 9);
System.out.println("原集合:=》" + randomCollection1);
List<Integer> reverse = Lists.reverse(randomCollection1);
System.out.println("颠倒后:=》" + reverse);
}
Objects
Java.util包下的Objects类为我们提供了操作对象的工具类
判空
由于
Objects只有当对象为NULL时才会判空,一般来说我们就用Spring提供的工具类BeanUtils来判空。
/**
* 判空
* 只有当对象为null时返回true
*/
@Test
public void isNull() {
String string = new String();
System.out.println(Objects.isNull(string));
}
/**
* spring提供的判空
*/
@Test
public void springBeanUtils() {
System.out.println(ObjectUtils.isEmpty(""));
}
为空抛异常
当对象为空时抛出异常,
Assert也可以实现。
/**
* 为空抛出异常
*/
@Test
public void ifNullThrow() {
Object obj = null;
//自定义异常信息
Objects.requireNonNull(obj, "参数为空");
//使用函数式接口,自定义异常
Objects.requireNonNull(obj, () -> {
return "参数为空";
});
}
判断两个对象是否相等
- equals
- deepEquals(可以判断数组)
/**
* 判断两个对象是否相等
* 判断逻辑:两个对象完全相等,或equals方法返回true
*/
@Test
public void isEquals() {
String str1 = "abc";
String str2 = "abc";
String str3 = "123";
System.out.println(Objects.equals(str1, str2));
System.out.println(Objects.equals(str1, str3));
}
好处:
避免空指针异常
/**
* 使用Objects工具类,如果前者为null,是否抛出空指针异常
*
* 不会
*/
@Test
public void shouldNullException() {
Object obj1 = null;
Object obj2 = new Object();
//会抛出空指针异常
obj1.equals(obj2);
//使用Objects工具类则不会抛出异常
Objects.equals(obj1, obj2);
}
比较的坑:
- 基本数据类型自动拆箱空指针问题
- 不同数据类型会装箱后再调用equals比较,数据类型不匹配直接返回false
/**
* 对于基本数据类型比较的坑
* 如果是基本数据类型的包装类型和基本数据类型比较的话,需要注意自动拆箱的空指针异常
*/
@Test
public void testSimpleType() {
Integer i1 = null;
int i2 = 0;
//抛出空指针异常
System.out.println(i1 == i2);
}
@Test
public void testSimpleType2() {
long i1 = 1L;
Integer i2 = 1;
//true
System.out.println(1 == 1L);
//true
System.out.println(i1 == i2);
//false 这里是自动装箱的问题。long会装箱成Long 而不同类型的equals方法会返回false
System.out.println(Objects.equals(i1, i2));
}
获取hashCode
使用
Object的HashCode()方法存在空指针危险,Objects则不会,当对象为空返回0.
就是加了一层判空逻辑
/**
* 获取对象的hashCode
*/
@Test
public void getHashCode() {
String str = "1223";
//重写Object的hashCode方法,如多str为空会报空指针异常
System.out.println(str.hashCode());
//这里处理的好,为空返回0,不为空再调用hashCode方法
System.out.println(Objects.hashCode(str));
}
BooleanUtils
布尔值工具类,同样的可以避免空指针异常。在Apache.common包下
可以返回非true,也就是false或者null
某些场景会对布尔值做转化,true - 1 false-0
int类型或String类型可以转化为Boolean类型
@Test
public void booleanUtils() {
Boolean b = false;
//将int转化为boolean
System.out.println(BooleanUtils.toBoolean(1));
System.out.println(BooleanUtils.toBoolean(1, 1, 0));
//将String转化为boolean
System.out.println(BooleanUtils.toBoolean("true"));
System.out.println(BooleanUtils.toBoolean("abc","abc","123"));
//将boolean转化为int或integer
System.out.println(BooleanUtils.toInteger(b, 1, 0));
//转化为String,可以制定 "true/"false"、"off"/"on"等等
System.out.println(BooleanUtils.toStringOnOff(b));
//判断某个布尔值是否为true或false即便为null也没事
System.out.println(BooleanUtils.isFalse(b));
System.out.println(BooleanUtils.isTrue(null));
System.out.println(BooleanUtils.isNotTrue(null));
}
StringUtils
字符串工具类,在apache.common包下
对于字符串的处理时很频繁的,判空、截取、转换大小写等等
判空
一般使用isBlank方法,因为此方法会将 “ ”空行考虑进去
@Test
public void isEmpty() {
//字符串对象为null或没有字符串长度为0
System.out.println(StringUtils.isEmpty(""));
System.out.println(StringUtils.isEmpty(" "));
//判断字符串是否为空行
System.out.println(StringUtils.isBlank(" "));
}
分隔字符串
/**
* 分隔字符串
*/
@Test
public void split() {
String str = "1。2。3。4。5。6。7。8。9";
//使用String的Split当字符串对象为空时会抛出空指针异常
System.out.println(Arrays.toString(str.split("。", 4)));
//使用StringUtils避免空指针异常
System.out.println(Arrays.toString(StringUtils.split(str, "。", 3)));
}
判断字符串是否为纯数字
我们使用Integer.valueOf()方法之前可以使用,isNumeric(String)判断字符串是否为纯数字
/**
* 判断给定的字符串是否为纯数字
*/
@Test
public void testIsNumeric() {
String str1 = "123";
String str2 = "0.123";
String str3 = "0.123f";
String str4 = "123L";
System.out.println(str1+"=>"+StringUtils.isNumeric(str1));
System.out.println(str2+"=>"+StringUtils.isNumeric(str2));
System.out.println(str3+"=>"+StringUtils.isNumeric(str3));
System.out.println(str4+"=>"+StringUtils.isNumeric(str4));
}
将集合拼接成字符串
首先会截取我们的数组,然后循环调用集合内对象的toString方法,用StringBuffer拼接起来返回。
/**
* 将集合拼接成字符串,并自定义分隔符
*/
@Test
public void join() {
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
final String join = StringUtils.join(list, ",", 0, list.size());
System.out.println(join);
}
Assert
Assert为断言的意思,很多情况下可以用于判段参数是否符合条件,否则抛出异常,且可以统一处理
参数不符合条件,会抛出java.lang.IllegalArgumentException异常
这里使用的是springframework.util下的工具类
判空
/**
* 断言为空或不为空
* - 对象
* - 集合
* - map
*/
@Test
public void testIsNull() {
String str= null;
Assert.notNull(str,"参数不可以为空");
Assert.isNull(str,"参数必须为空");
Lists.newArrayList(1,2,3,4);
Assert.notEmpty((Object[]) null,"不可以为空");
}
布尔值及其他
/**
* 断言布尔值
*/
@Test
public void assertBoolean() {
final List<Object> list = Lists.newArrayList();
Assert.isTrue(!list.isEmpty(), "集合不可以为空");
}
/**
* 断言是否符合类型
*/
@Test
public void assertInstance() {
Assert.isInstanceOf(Integer.class, "abc", "类型不匹配");
Assert.isAssignable(String.class, Object.class);
}
/**
* 断言类型是否可以强转
* - 存在父子关系
* - 接口和其实现类
*/
@Test
public void assertAssignable() {
//通过
Assert.isAssignable(List.class, ArrayList.class);
//通过
Assert.isAssignable(Object.class, ArrayList.class);
//可以
Assert.isAssignable(Collection.class, List.class);
//可以
Assert.isAssignable(Collection.class, ArrayList.class);
//不通过
Assert.isAssignable(List.class, Object.class);
}