Java外部工具类
1、Apache Commons 工具类
它包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动。https://commons.apache.org/
1.1、Lang3
是一个公共的工具合集,涵盖了字符串操作、数组操作、JVM交互操作等,用的最新的3版本,所以叫Lang3
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
StringUtils
判断字符串是否为空或空格
@Test
public void StringUtilsTest1(){
String str = " ";
System.out.println("字符串str是否为空格:"+StringUtils.isBlank(str));
System.out.println(StringUtils.isNotBlank(str)); //反过来
System.out.println("字符串str是否为空:"+StringUtils.isEmpty(str));
System.out.println(StringUtils.isNotEmpty(str));
}
电话号码脱敏
String tel = "13986215432";
String left = StringUtils.left(tel, 3);
String right = StringUtils.right(tel, 4);
System.out.println(left +"****"+ right); //139****5432
//方法二
//rightPad:如果left长度小于7,则在右边用*填充到7个长度(rightPad最后长度为7)
String rightPad = StringUtils.rightPad(left, 7, "*");
System.out.println(rightPad+right); //139****5432
对字符串中的HTML标签转义
//用户页面响应输出时候,不需要浏览器解析标签,直接以字符原本的面貌展现
String htmlTagStr="<h3>你好</h3>";
System.out.println("未转义前:"+htmlTagStr); //未转义前:<h3>你好</h3>
htmlTagStr= StringEscapeUtils.escapeHtml4(htmlTagStr);
System.out.println("html标签转义后:"+htmlTagStr); //html标签转义后:<h3>你好</h3>
StringEscapeUtils 这个类已经过期了,提醒使用新的替代类。新的替代类org.apache.commons.text.StringEscapeUtils
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.1</version>
</dependency>
其它方法
方法名 | 描述 |
---|---|
trim(str) | 只去除字符串首尾的空格 |
equals(str,"xiao") | 比较两个字符串是否相同,支持null |
joinWith(",", new String[]{"a", null, "b"}) | 连接字符串,结果为a,,b |
substringAfter(str,"feng") | 从某个字符后截取一段字符 |
substringAfterLast(joinStr,"-") | 从连接字符串的最后一个"-"之后截取 |
isNumeric("123") | 判断是否为数字型字符串 |
NumberUtils
判断一个参数(数字型字符)是不是数字(整数、浮点数)
String str1 = "256";
String str2 = "256.8";
String str3 = "256a";
String str4 = "+256";
//(1)isDigits只能判断整数,都是当作十进制来处理的
System.out.println(NumberUtils.isDigits(str1)); //true
System.out.println(NumberUtils.isDigits(str2)); //false
System.out.println(NumberUtils.isDigits(str3)); //false
//(2)isParsable可以判断是不是整数、浮点数;不能识别正负,都是当作十进制来处理的
System.out.println(NumberUtils.isParsable(str2)); //true
System.out.println(NumberUtils.isParsable(str4)); //false
//(3)isCreatable可以判断是不是整数、浮点数,识别正负,以及进制
System.out.println(NumberUtils.isCreatable(str4)); //true
System.out.println(NumberUtils.isCreatable("09")); //false,8进制中没有9
数字型字符转换成int或double类型数字
String numberStr = "234";
System.out.println(NumberUtils.toInt(numberStr)); //234
System.out.println(NumberUtils.toDouble(numberStr)); //234.0
//字符串转换为double类型,如果字符串格式不对或者为null,则返回double默认值0.0,并不会抛出异常
System.out.println(NumberUtils.toDouble("12a")); //0.0
System.out.println(NumberUtils.toDouble("")); //0.0
ObjectUtils
str1,str2,str3...取第一个不为空的作为结果使用
String str1 = null;
String str2 = null;
String str3 = "str3";
System.out.println(ObjectUtils.firstNonNull(str1, str2, str3));
RandomUtils
//(1)生成随机数字;随机产生0-10范围内的整数,包括0,不包括10,左闭右开
System.out.println(RandomUtils.nextInt(0, 10));
//(2)随机生成4个字符,组成一个字符串(包含字母和数字)
//String random(final int count, final boolean letters, final boolean numbers)
System.out.println(RandomStringUtils.random(4, true, true));//1qP3
//(3)随机生成5个字符,包含(数字)和字母
System.out.println(RandomStringUtils.randomAlphabetic(5));//xkZUI
System.out.println(RandomStringUtils.randomAlphanumeric(5));//9CW70
DateUtils
设置年份
Date date = DateUtils.setYears(new Date(),2021);
String dateStr = DateFormatUtils.format(date,"YYYY-MM-dd HH:mm:ss");
System.out.println("设置年份后的日期为:"+dateStr);
ArrayUtils
判断一个数组是否为空或0,免去了写很多判断
Integer[] int1 = new Integer[1];
Integer[] int2 = new Integer[0];
System.out.println(ArrayUtils.isEmpty(int1));//false
int1 = null;
System.out.println(ArrayUtils.isEmpty(int2));//true
System.out.println(ArrayUtils.isEmpty(int1));//true
给已有数组添加元素
int[] myInt = new int[1];
myInt[0] = 3;
System.out.println(ArrayUtils.toString(myInt));
//myInt[1] = 9; 报错:下标越界
//add()会自动创建新的数组
int[] newInt = ArrayUtils.add(myInt, 9);
System.out.println(ArrayUtils.toString(newInt));
//合并两个数组arr1、arr2, 相当于复制扩充了一个新数组
String[] arrayUnion=ArrayUtils.addAll(arr1,arr2);
ClassUtils
1.2、Collections
对java.util的扩展封装,处理数据还是挺灵活的。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
判断list、set、map是否为空(null/size>0),取值
List<String> list = new ArrayList<>();
System.out.println(CollectionUtils.isEmpty(list));//true
Map<String,String> map = new HashMap<>();
System.out.println(MapUtils.isEmpty(map));
//获取map中key为a的值,并转换为Integer
MapUtils.getInteger(map,"a");
交集、并集、差集
List<String> list1 = new ArrayList<>();
list1.add("a"); list1.add("b"); list1.add("c");
List<String> list2 = new ArrayList<>();
list2.add("c"); list2.add("1"); list2.add("2");
//交集:[c]
System.out.println(CollectionUtils.intersection(list1, list2));
//并集:[a, 1, b, 2, c]
System.out.println(CollectionUtils.union(list1, list2));
//差集:[a, b] = [a, b, c]-[c, 1, 2]
System.out.println(CollectionUtils.subtract(list1, list2));
//差集:[1, 2]
System.out.println(CollectionUtils.subtract(list2, list1));
1.3、I/O
对java.io的扩展 操作文件非常方便
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
FileUtils
readFileToString:读取指定的文本文件的内容为字符串
String path = "src\\main\\java\\apacheCommons\\io.txt";
File file = new File(path);
String str = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
System.out.println(str); //读到了每一行的内容
readLines:读取指定的文本文件的内容为List<String>
String path = "src\\main\\java\\apacheCommons\\io.txt";
File file = new File(path);
List<String> strs = FileUtils.readLines(file, StandardCharsets.UTF_8);
System.out.println(strs); //[123, 89fv, 阿萨德]
FilenameUtils
getExtension:读取文件的后缀、basename(io.txt)
String path = "src\\main\\java\\apacheCommons\\io.txt";
//获取文件后缀
System.out.println(FilenameUtils.getExtension(path)); //txt
//获取文件basename
System.out.println(FilenameUtils.getBaseName(path)); //io
IOUtils
通过URL读取网页内容:
- 1 通过URL对象的openStream()方法能够得到指定资源的输入流。
- 2 通过输入流能够读取、访问网络上的数据。
使用IOUtils只需要一行代码,就可以读取到网页内容,减少了很多代码
InputStream inputStream = new URL("http://www.baidu.com").openStream();
//StandardCharsets.UTF_8等价于"utf-8"
String webPageContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
System.out.println(webPageContent);
2、Guava Google核心类库
Guava中包含了Google的一些核心类库:比如集合,缓存,并发包,常用注解,字符串处理,I/O等等。
1.字符串的处理:分割,连接,填充
on():指定字符串的分隔符
joiner 连接器
Joiner:把集合或数组或可变参数,通过指定的分隔符连接变成字符串。连接的时候list里面含有null值,会报空指针。原因在于join方法的实现底层StringBuilder。
-
skipNulls():连接跳过null元素
-
useForNull(final String value):用value替换null元素值
List<String> list1 = Lists.newArrayList("a","b","g","8","9");
Joiner joiner = Joiner.on(",");
String res = joiner.join(list1);
System.out.println(res); //a,b,g,8,9
List<String> list2 = Lists.newArrayList("a",null,"8","9");
System.out.println(Joiner.on(",").skipNulls().join(list2)); //a,8,9
System.out.println(Joiner.on(",").useForNull("replaceNull").join(list2)); //a,replaceNull,8,9
splitter 拆分器
Splitter:通过指定的分隔符吧字符串转为集合
splitToList():进到字符串组件中,并将它们作为不可变列表返回。
- omitEmptyStrings(): 去除拆分出来空的字符串
- trimResults(): 拆分去除前后空格
- fixedLength(int lenght): 把字符串按固定长度分割
String str = "12,fgfd,地方";
Splitter splitter = Splitter.on(",");
List<String> list = splitter.splitToList(str);
System.out.println(list); //[12, fgfd, 地方]
Splitter.on(",").omitEmptyStrings().splitToList(str);
Splitter.on(",").trimResults().splitToList(str);
下划线和驼峰互转 myInt<--->my_int
//将下划线转为驼峰
String str = "my_int";
String res = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, str);
System.out.println(res); //myInt
//将驼峰转为下划线
CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, res); //my_int
2.Lists的用法(Sets、Maps)
提供集合的快速创建方法
//JDK
List<String> list = new ArrayList<String>();
list.add("a"); list.add("b");
//Lists
ArrayList<String> list = Lists.newArrayList("a", "b");
需求:用户传一些ids,一次最多20个
partition():把list分成大小为size的一个个小的集合
ArrayList<String> list = Lists.newArrayList("a","b","c","d");
//把list分成小的集合,小的集合的大小为size
List<List<String>> partition = Lists.partition(list, 2);
System.out.println(partition); // [[a, b], [c, d]]
//原生写法:循环list.subList(0, 2);
for(List<String> ids: partition){
//调用相关api(ids);
}
3.Ints、Floats、Longs
将int型新建为list:
List<Integer> list = Ints.asList(1, 2, 3);//[1, 2, 3]
4.Multimap,允许相同key的map
Multimap就是将相同key的value值放在一个list里面,这样子取相同key下面的所有value值就非常简单了,
不然还得for循环去匹配,把相同key值的value值找出来,在进行处理。
map<key,value>键值key不能重复,所以当遇到这样子场景的时候map就非常不适合了,guava提供了Multimap适用于该场景。
Multimap<String,String> multimap = HashMultimap.create();
举例:当我们需要一个map中包含key为String类型,value为List类型的时候,以前我们是这样写的
// jdk方式
Map<String, List<Integer>> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
list.add(1); list.add(2);
map.put("num",list);
System.out.println(map.get("num")); //[1, 2]
ArrayListMultimap.create():允许相同key
// guava方式
ArrayListMultimap<String, Integer> map = ArrayListMultimap.create();
map.put("num",1); map.put("num",2);
map.put("num1",2); map.put("num1",2);
map.put("num2",8);
System.out.println(map.get("num3")); //[]
System.out.println(map.get("num")); //[1, 2]
System.out.println(map.keys()); //[num x 2, num1 x 2, num2]
System.out.println(map.size()); //5个value
Multimap.get(key)即使没有key值,会返回空的list。
Multimap.keySet()返回的用set
Multimap.keys()返回的是用Multiset表示的key,key数量跟value值数量一致;
Multimap.containKeys()是表示是否包含这个key;
Multimap.size()返回所有值的个数,而非不同键的个数。要得到不同键的个数,要用Multimap.keySet().size()
5.Multiset,元素可重复且有序的set
list:元素可重复的有序集合,set:元素不可重复的无序集合
Multiset<String> multiset = HashMultiset.create();
multiset.add("a");
multiset.add("c");
multiset.add("a");
multiset.add("b");
System.out.println(multiset); //[a x 2, b, c]
System.out.println(multiset.entrySet()); //[a x 2, b, c]
System.out.println(multiset.elementSet()); //[a, b, c]
6.ImmutableList不可变集合
另外还有ImmutableSet、ImmutableIntArray。。。
用途:当把list放入缓存里面时,使用不可变集合可以防止他人篡改。
ImmutableList<Object> immutableList = ImmutableList.builder().add("num").build();
//把immutableList放入缓存
immutableList.add("num1"); //运行报错:UnsupportedOperationException
7.Preconditions数据校验
String param = null;
Preconditions.checkNotNull(param, "不能为null");
//NullPointerException: 不能为null
//第一个参数是一个expression:布尔值表达式,true:校验通过,不抛异常
Preconditions.checkArgument(param!=null, "不能为null");
//IllegalArgumentException: 不能为null
3、Spring 工具类
Spring中的工具类
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
ClassUtils
用途:先判断某个类是否存在,然后再做某些事情。
判断当前应用是否加载了com.Test这样的一个类
String className = "com.Test";
boolean b = ClassUtils.isPresent(className, null);
System.out.println(b); //false
ReflectionUtils
ReflectionUtils.doWithFields():获取本类以及所有的父类(包含父类的父类)的所有属性
ReflectionUtils.doWithMethods():获取所有方法
//ReflectionUtils不要导错包,Person为自定义类
ReflectionUtils.doWithFields(Person.class, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
System.out.println(field.getName()); //name age
}
});
//简写
ReflectionUtils.doWithFields(Person.class
, field-> System.out.println(field.getName()));
反射获得某个属性的值
Person person = new Person("jack", 22);
ReflectionUtils.doWithFields(Person.class, field-> {
//设置所有属性的可访问
field.setAccessible(true);
Object fieldValue = ReflectionUtils.getField(field, person);
System.out.println(fieldValue); //jack 22
});
BeanUtils
拷贝对象
Person man = new Person("jack", 22);
Person copyMan = new Person();
BeanUtils.copyProperties(man,copyMan);
System.out.println(copyMan); //Person{name='jack', age=22}
FileCopyUtils?
。。。
GenericTypeResolver泛型解析?
spring提供的泛型解析工具类,用于解析当前类所使用的泛型Class,用于适配某些特定场景需求以及设计模式中。
//1、定义接口
public interface MyInterface<T> {
void testMethod(T event);
}
//2、定义实现类
public class MyImpl implements MyInterface<String>{
@Override
public void testMethod(String event) {
...
}
}
//3、测试
public static void main(String[] args) {
MyImpl dffImpl = new MyImpl();
Class<?> aClass = GenericTypeResolver.resolveTypeArgument(dffImpl.getClass(), MyInterface.class);
System.out.println(aClass);
}
//4、输出结果
class java.lang.String
https://www.bilibili.com/video/BV1Lv411P7Ua
详细:https://blog.csdn.net/u011174699/article/details/105863949
guava:https://blog.csdn.net/h2604396739/article/details/109091000
GenericTypeResolver使用:https://blog.csdn.net/luoxiaomei999/article/details/114368867
Arrays:https://zhuanlan.zhihu.com/p/105076434