该系列文章主要是对 hutool 工具类的介绍,详情可以参考
19 hutool-core
封装了一些通用的工具类,是整个 hutool 工具包的核心
注解工具 - AnnotationUtil
@Test
public void testGetAnnotation() {
MyAnnotation annotation = AnnotationUtil.getAnnotation(ClassWithAnnotation.class, MyAnnotation.class);
Console.log(annotation.value());
}
@Test
public void getAnnotationValue() {
Object value = AnnotationUtil.getAnnotationValue(ClassWithAnnotation.class, MyAnnotation.class);
Console.log(value);
}
Bean工具 - BeanUtil
把一个拥有对属性进行set和get方法的类,我们就可以称之为JavaBean。
Bean工具类主要是针对这些setXXX和getXXX方法进行操作,比如将Bean对象转为Map等等。
@Test
public void isBean() {
// 根据是否存在只有一个参数的setXXX方法或者public类型的字段来判定是否是一个Bean对象
boolean isBean = BeanUtil.isBean(HashMap.class);
Console.log(isBean);
}
@Test
public void fillBean() {
final Person person = BeanUtil.fillBean(new Person(), new ValueProvider<String>() {
@Override
public Object value(final String key, final Type valueType) {
switch (key) {
case "name":
return "张三";
case "age":
return 18;
}
return null;
}
@Override
public boolean containsKey(final String key) {
// 总是存在key
return true;
}
}, CopyOptions.create());
Console.log(person);
}
@Test
public void mapToBeanIgnoreCaseTest() {
final HashMap<String, Object> map = MapUtil.newHashMap();
map.put("Name", "Joe");
map.put("aGe", 12);
final Person person = BeanUtil.fillBeanWithMapIgnoreCase(map, new Person(), false);
Console.log(person);
}
@Test
public void toMap() {
final Person person = new Person();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试A11");
final Map<?, ?> map = BeanUtil.beanToMap(person);
Console.log(map);
}
@Test
public void dynaBeanTest() {
Person person = new Person();
// 像操作 map 一样动态操作 Bean
DynaBean bean = DynaBean.create(person);
bean.set("name", "李华");
bean.set("age", 12);
String name = bean.get("name");
Assert.assertEquals(person.getName(), name);
int age = bean.get("age");
Assert.assertEquals(person.getAge(), age);
//执行指定方法
Object invoke = bean.invoke("testMethod");
Console.log(invoke);
}
支持泛型的克隆接口和克隆类
-
引用拷贝 创建一个指向对象的引用变量的拷贝。地址一样,引用改变了。
-
对象拷贝 重新开辟一块地址空间。以下提的深拷贝和浅拷贝都是对象拷贝
-
深拷贝 会对对象里的对象进行拷贝
-
浅拷贝 不会对对象里的对象进行拷贝
@Test
public void cloneTest() throws Exception {
Cat cat1 = new Cat();
Cat cat2 = (Cat) cat1.clone();
Console.log("cat1:{}", cat1);
Console.log("cat2:{}", cat2);
Dog dog1 = new Dog();
Dog dog2 = dog1.clone();
Console.log("dog1:{}", dog1);
Console.log("dog2:{}", dog2);
}
@Test
public void cloneTestV2() {
Car car1 = new Car();
Car car2 = car1.clone();
Console.log("car1:{}", car1);
Console.log("car2:{}", car2);
}
Cat 实现 jdk 的 Cloneable 接口
public class Cat implements Cloneable {
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Dog 实现hutool 的 Cloneable 接口,强制实现 clone 方法
public class Dog implements Cloneable<Dog> {
@Override
public Dog clone() {
try {
return (Dog) super.clone();
} catch (CloneNotSupportedException e) {
throw new CloneRuntimeException(e);
}
}
}
Car 继承 CloneSupport 类,有默认的 clone 方法实现
public class Car extends CloneSupport<Car> {
private String name;
}
Codec编码
Base62
短链接生成
Base64
Base64编码是用64(2的6次方)个ASCII字符来表示256(2的8次方)个ASCII字符,也就是三位二进制数组经过编码后变为四位的ASCII字符显示,长度比原来增加1/3。
莫尔斯电码-Morse
摩尔斯电码也被称作摩斯密码,是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。
摩尔斯电码是由点dot(.)划dash(-)这两种符号所组成的。
BCD码
BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
回转N位密码-Rot
RotN(rotate by N places),回转N位密码,是一种简易的替换式密码,也是过去在古罗马开发的凯撒加密的一种变体。
@Test
public void base62() {
String a = "www.baidu.com";
String encode = Base62.encode(a);
Console.log(encode);
String decodeStr = Base62.decodeStr(encode);
Console.log(decodeStr);
}
@Test
public void base64() {
String a = "hello world";
String encode = Base64.encode(a);
Console.log(encode);
String decodeStr = Base64.decodeStr(encode);
Console.log(decodeStr);
}
@Test
public void morse() {
Morse morseCoder = new Morse();
String text = "Hello World!";
String encode = morseCoder.encode(text);
Console.log(encode);
String decodeStr = morseCoder.decode(encode);
Console.log(decodeStr);
}
@Test
public void bcd() {
String text = "123456ABCDEF";
//转BCD
byte[] bcd = BCD.strToBcd(text);
Console.log(new String(bcd, StandardCharsets.UTF_8));
//解码BCD
String str = BCD.bcdToStr(bcd);
Console.log(str);
}
@Test
public void rot() {
String str = "1f2e9df6131b480b9fdddc633cf24996";
String encode13 = Rot.encode13(str);
Console.log(encode13);
String decode13 = Rot.decode13(encode13);
Console.log(decode13);
}
集合工具
操作集合类的方法,许多方法都是通过 stream 流来实现的,对于习惯用 stream 流来排序,过滤的开发者,没必要强制使用工具类
@Test
public void newArrayListTest() {
ArrayList<String> list = CollUtil.newArrayList("a", "b", "c");
for (String str : list) {
Console.log(str);
}
}
@Test
public void joinTest() {
String[] col = new String[]{"a", "b", "c", "d", "e"};
List<String> colList = CollUtil.newArrayList(col);
String str = CollUtil.join(colList, "#");
// a#b#c#d#e
Console.log(str);
}
@Test
public void sortPageAllTest() {
// 新建三个列表,CollUtil.newArrayList方法表示新建ArrayList并填充元素
List<Integer> list1 = CollUtil.newArrayList(1, 2, 3);
List<Integer> list2 = CollUtil.newArrayList(4, 5, 6);
List<Integer> list3 = CollUtil.newArrayList(7, 8, 9);
// 参数表示把list1,list2,list3合并并按照从小到大排序后,取0~2个(包括第0个,不包括第2个),结果是[1,2]
List<Integer> result = CollUtil.sortPageAll(0, 10, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
}, list1, list2, list3);
// 合并 + 排序 + 分页
for (Integer integer : result) {
Console.log(integer);
}
}
@Test
public void removeWithAddIfTest() {
ArrayList<Integer> list = CollUtil.newArrayList(1, 2, 3);
// 过滤条件,ele == 1
List<Integer> resultList = CollUtil.removeWithAddIf(list, ele -> 1 == ele);
// 过滤删除了 1 ,[2,3]
Console.log(list);
// 过滤的数组, [1]
Console.log(resultList);
// 也可以将返回的数组当参数传入
list = CollUtil.newArrayList(1, 2, 3);
resultList = new ArrayList<>();
CollUtil.removeWithAddIf(list, resultList, ele -> 2 == ele);
// 过滤删除了 2 ,[1,3]
Console.log(list);
// 过滤的数组, [2]
Console.log(resultList);
}
@Test
public void padTest() {
List<String> srcList = CollUtil.newArrayList();
// 左边补 b,直到长度为 1
CollUtil.padLeft(srcList, 1, "b");
// 左边补 a,直到长度为 2
CollUtil.padLeft(srcList, 2, "a");
// [a,b]
Console.log(srcList);
// 左边补 a,直到长度为 4
CollUtil.padLeft(srcList, 4, "a");
// [a,a,a,b]
Console.log(srcList);
// 右边补 c,直到长度为 10
CollUtil.padRight(srcList, 10, "c");
// [a, a, a, b, c, c, c, c, c, c]
Console.log(srcList);
}
@Test
public void unionTest() {
ArrayList<String> list1 = CollUtil.newArrayList("a", "b", "b", "c", "d", "x");
ArrayList<String> list2 = CollUtil.newArrayList("a", "b", "b", "b", "c", "d");
// 取交集
Collection<String> union = CollUtil.union(list1, list2);
// [a, b, b, b, c, d, x]
Console.log(union);
}
@Test
public void intersectionTest() {
ArrayList<String> list1 = CollUtil.newArrayList("a", "b", "b", "c", "d", "x");
ArrayList<String> list2 = CollUtil.newArrayList("a", "b", "b", "b", "c", "d");
// 取并集
Collection<String> intersection = CollUtil.intersection(list1, list2);
// [a, b, b, c, d]
Console.log(intersection);
}
@Test
public void intersectionDistinctTest() {
ArrayList<String> list1 = CollUtil.newArrayList("a", "b", "b", "c", "d", "x");
ArrayList<String> list2 = CollUtil.newArrayList("a", "b", "b", "b", "c", "d");
// 取并集并去重
Collection<String> intersectionDistinct = CollUtil.intersectionDistinct(list1, list2);
// [a, b, c, d]
Console.log(intersectionDistinct);
}
@Test
public void subtractTest() {
ArrayList<String> list1 = CollUtil.newArrayList("a", "b", "b", "c", "d", "x");
ArrayList<String> list2 = CollUtil.newArrayList("a", "b", "b", "b", "c", "d", "x2");
// 取差集,在 1 不在 2
Collection<String> subtract = CollUtil.subtract(list1, list2);
// [x]
Console.log(subtract);
// 取差集,在 2 不在 1
Collection<String> subtract2 = CollUtil.subtract(list2, list1);
// [x2]
Console.log(subtract2);
}
@Test
public void testToList() {
ArrayList<String> list = ListUtil.toList("a", "b", "c");
Console.log(list);
}
@Test
public void testIndexOfAll() {
List<String> list = ListUtil.toList("1", "2", "3", "2", "3", "2", "3");
int[] index = ListUtil.indexOfAll(list, (str) -> {
return "2".equals(str);
});
Console.log(index);
}
比较器
在JDK提供的比较器中,对于null的比较没有考虑,Hutool封装了相关比较,可选null是按照最大值还是最小值对待。
@Test
public void compareTest() {
int compare = CompareUtil.compare(null, "a", true);
Console.log(compare > 0);
compare = CompareUtil.compare(null, "a", false);
Console.log(compare < 0);
}
@Test
public void comparingPinyin() {
List<String> list = ListUtil.toList("成都", "北京", "上海", "深圳");
List<String> ascendingOrderResult = ListUtil.of("北京", "成都", "上海", "深圳");
List<String> descendingOrderResult = ListUtil.of("深圳", "上海", "成都", "北京");
// 正序
list.sort(CompareUtil.comparingPinyin(e -> e));
// ["北京", "成都", "上海", "深圳"]
Console.log(list, ascendingOrderResult);
// 反序
list.sort(CompareUtil.comparingPinyin(e -> e, true));
// ["深圳", "上海", "成都", "北京"]
Console.log(list, descendingOrderResult);
}
类型转换
@Test
public void toStrTest() {
int a = 1;
long[] b = {1, 2, 3, 4, 5};
String aStr = Convert.toStr(a);
// 1
Console.log(aStr);
String bStr = Convert.toStr(b);
// [1, 2, 3, 4, 5]
Console.log(Convert.toStr(bStr));
}
@Test
public void toIntTest() {
String a = " 34232";
Integer aInteger = Convert.toInt(a);
// 34232
Console.log(aInteger);
// 带小数测试
String b = " 34232.00";
Integer bInteger = Convert.toInt(b);
// 34232
Console.log(bInteger);
// boolean测试
boolean c = true;
Integer cInteger = Convert.toInt(c);
// 1
Console.log(cInteger);
// str测试
String d = "08";
Integer dInteger = Convert.toInt(d);
// 8
Console.log(dInteger);
}
@Test
public void toDateTest() {
Date date = Convert.toDate("2022-10-25");
Console.log(date);
}
@Test
public void toListTest() {
List<String> list = Arrays.asList("1", "2");
String str = Convert.toStr(list);
// [1,2]
Console.log(str);
List<String> list2 = Convert.toList(String.class, str);
// [1,2]
Console.log(list2);
List<Integer> list3 = Convert.toList(Integer.class, str);
// [1,2]
Console.log(list3);
}
@Test
public void toListTest2() {
Object[] a = {"a", "你", "好", "", 1};
List<String> list = Convert.convert(new TypeReference<List<String>>() {
}, a);
// [a, 你, 好, , 1]
Console.log(list);
}
@Test
public void hexTest() {
String a = "hello world";
String hex = Convert.toHex(a, CharsetUtil.CHARSET_UTF_8);
Console.log(hex);
String raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);
Console.log(raw);
}
@Test
public void unicodeTest() {
String a = "hello world";
String unicode = Convert.strToUnicode(a);
Console.log(unicode);
String raw = Convert.unicodeToStr(unicode);
Console.log(raw);
// 针对有特殊空白符的Unicode
String str = "你 好";
String unicode2 = Convert.strToUnicode(str);
Console.log(unicode2);
String str2 = Convert.unicodeToStr(unicode2);
Console.log(str2);
}
@Test
public void convertCharsetTest() {
String a = "我不是乱码";
// 转换后result为乱码
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
Console.log(result);
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Console.log(raw);
Assert.assertEquals(raw, a);
}
日期时间
@Test
public void nowTest() {
// 当前时间
final Date date = DateUtil.date();
Console.log(date);
// 当前时间
final Date date2 = DateUtil.date(Calendar.getInstance());
Console.log(date2);
// 当前时间
final Date date3 = DateUtil.date(System.currentTimeMillis());
Console.log(date3);
// 当前日期字符串,格式:yyyy-MM-dd HH:mm:ss
final String now = DateUtil.now();
Console.log(now);
// 当前日期字符串,格式:yyyy-MM-dd
final String today = DateUtil.today();
Console.log(today);
}
@Test
public void formatAndParseTest() {
final String dateStr = "2022-10-25";
final Date date = DateUtil.parse(dateStr);
final String format = DateUtil.format(date, "yyyy/MM/dd");
Console.log(format);
// 常用格式的格式化
final String formatDate = DateUtil.formatDate(date);
Console.log(formatDate);
final String formatDateTime = DateUtil.formatDateTime(date);
Console.log(formatDateTime);
final String formatTime = DateUtil.formatTime(date);
Console.log(formatTime);
}
@Test
public void beginAndEndTest() {
final Date date = DateUtil.date();
// 一天的开始
final Date beginOfDay = DateUtil.beginOfDay(date);
Console.log(beginOfDay);
// 一天的结束
final Date endOfDay = DateUtil.endOfDay(date);
Console.log(endOfDay);
}
@Test
public void offsetDateTest() {
final Date date = DateUtil.date();
Console.log(date);
// 偏移天
final Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);
Console.log(newDate);
// 偏移天
final DateTime newDate2 = DateUtil.offsetDay(date, 3);
Console.log(newDate2);
// 偏移小时
final DateTime newDate3 = DateUtil.offsetHour(date, -3);
Console.log(newDate3);
// 偏移月
final DateTime offsetMonth = DateUtil.offsetMonth(date, -1);
Console.log(offsetMonth);
}
@Test
public void betweenTest() {
final String dateStr1 = "2017-03-01 22:34:23";
final Date date1 = DateUtil.parse(dateStr1);
final String dateStr2 = "2017-04-01 23:56:14";
final Date date2 = DateUtil.parse(dateStr2);
//相差一个月,31天
long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
Console.log(betweenDay);
}
@Test
public void formatBetweenTest() {
final String dateStr1 = "2017-03-01 22:34:23";
final Date date1 = DateUtil.parse(dateStr1);
final String dateStr2 = "2017-04-01 23:56:14";
final Date date2 = DateUtil.parse(dateStr2);
final long between = DateUtil.between(date1, date2, DateUnit.MS);
Console.log(between);
final String formatBetween = DateUtil.formatBetween(between, BetweenFormatter.Level.MINUTE);
Console.log(formatBetween);
}
@Test
public void getZodiacTest() {
// 摩羯座
Console.log(Zodiac.getZodiac(Month.JANUARY, 19));
// 天蝎座
Console.log(Zodiac.getZodiac(Month.NOVEMBER, 1));
// 天秤座
Console.log(Zodiac.getZodiac(Month.OCTOBER, 15));
}
@Test
public void getChineseZodiacTest() {
// 狗
Console.log(Zodiac.getChineseZodiac(1994));
// 猪
Console.log(Zodiac.getChineseZodiac(1995));
}
@Test
public void isLeapYear() {
// 是否是闰年
Console.log(DateUtil.isLeapYear(2022));
DateTime dateTime = DateUtil.parse("1995-10-15");
// 年龄
Console.log(DateUtil.ageOfNow(dateTime));
}
异常工具 ExceptionUtil
@Test
public void getMessage() {
RuntimeException runtimeException = new RuntimeException("hello world");
String message = ExceptionUtil.getMessage(runtimeException);
Console.log(message);
}
@Test
public void wrapRuntime() {
RuntimeException runtimeException = ExceptionUtil.wrapRuntime("hello world");
Console.log(runtimeException);
}
@Test
public void getCausedBy() {
RuntimeException runtimeException = new RuntimeException("hello world");
Throwable throwable = ExceptionUtil.getCausedBy(runtimeException, RuntimeException.class);
Console.log(throwable);
}
@Test
public void stacktraceToString() {
RuntimeException runtimeException = new RuntimeException("hello world");
String message = ExceptionUtil.stacktraceToString(runtimeException);
Console.log(message);
}
图片处理工具类
@Test
public void scaleTest() {
ImgUtil.scale(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_result.jpg"), 0.8f);
}
@Test
public void scaleByWidthAndHeightTest() {
ImgUtil.scale(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_result2.jpg"), 400, 100, Color.BLUE);
}
@Test
public void cutTest() {
ImgUtil.cut(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_cut.jpg"), new Rectangle(200, 200, 100, 100));
}
@Test
public void rotateTest() throws IOException {
Image image = ImgUtil.rotate(ImageIO.read(FileUtil.file("D:\\pictures\\hutool\\bg.jpg")), 180);
ImgUtil.write(image, FileUtil.file("D:\\pictures\\hutool\\bg_rotate.jpg"));
}
@Test
public void flipTest() {
ImgUtil.flip(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_flip.jpg"));
}
@Test
public void pressImgTest() {
ImgUtil.pressImage(
FileUtil.file("D:\\pictures\\hutool\\bg.jpg"),
FileUtil.file("D:\\pictures\\hutool\\bg_image.jpg"),
ImgUtil.read(FileUtil.file("D:\\pictures\\hutool\\noonelikeu.jpg")), 0, 0, 0.9f);
}
@Test
public void pressTextTest() {
ImgUtil.pressText(//
FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), //
FileUtil.file("D:\\pictures\\hutool\\bg_text.jpg"), //
"版权所有", Color.RED, //
new Font("黑体", Font.BOLD, 100), //
0, //
0, //
1f);
}
@Test
public void slice() {
ImgUtil.slice(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_slice.jpg"), 1, 5);
}
@Test
public void convertTest() {
ImgUtil.convert(FileUtil.file("D:\\pictures\\hutool\\bg.jpg"), FileUtil.file("D:\\pictures\\hutool\\bg_convert.png"));
}
@Test
public void backgroundRemovalTest() {
// 图片 背景 换成 透明的
ImgUtil.backgroundRemoval(
"D:\\pictures\\hutool\\noonelikeu.jpg",
"D:\\pictures\\hutool\\noonelikeu_removal.jpg", 10);
// 图片 背景 换成 红色的
ImgUtil.backgroundRemoval(new File(
"D:\\pictures\\hutool\\noonelikeu.jpg"),
new File("D:\\pictures\\hutool\\noonelikeu_red.jpg"),
new Color(200, 0, 7), 10);
}
IO 流相关
IO的操作包括读和写,应用场景包括网络操作和文件操作。IO操作在Java中是一个较为复杂的过程,我们在面对不同的场景时,要选择不同的InputStream和OutputStream实现来完成这些操作。而如果想读写字节流,还需要Reader和Writer的各种实现类。这些繁杂的实现类,一方面给我我们提供了更多的灵活性,另一方面也增加了复杂性。
@Test
public void copyTest() {
BufferedInputStream inputStream = FileUtil.getInputStream("D:\\pictures\\hutool\\bg.jpg");
BufferedOutputStream outputStream = FileUtil.getOutputStream("D:\\pictures\\hutool\\bg_out.jpg");
IoUtil.copy(inputStream, outputStream);
}
@Test
public void readLinesTest() {
List<String> list = ListUtil.toList();
try (BufferedReader reader = ResourceUtil.getUtf8Reader("io/test.csv")) {
IoUtil.readLines(reader, list);
} catch (IOException e) {
throw new IORuntimeException(e);
}
for (String s : list) {
Console.log(s);
}
}
Map工具-MapUtil
@Test
public void filterTest() {
Map<String, String> map = MapUtil.newHashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("d", "4");
Map<String, String> map2 = MapUtil.filter(map, t -> Convert.toInt(t.getValue()) % 2 == 0);
// {b=2, d=4}
Console.log(map2);
}
@Test
public void editTest() {
Map<String, String> map = MapUtil.newHashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("d", "4");
Map<String, String> map2 = MapUtil.edit(map, t -> {
// 修改每个值使之*10
t.setValue(t.getValue() + "0");
return t;
});
// {a=10, b=20, c=30, d=40}
Console.log(map2);
}
@Test
public void reverseTest() {
Map<String, String> map = MapUtil.newHashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("d", "4");
Map<String, String> map2 = MapUtil.reverse(map);
// {1=a, 2=b, 3=c, 4=d}
Console.log(map2);
}
@Test
public void sortJoinTest() {
Map<String, String> build = MapUtil.builder(new HashMap<String, String>())
.put("key1", "value1")
.put("key3", "value3")
.put("key2", null).build();
String join1 = MapUtil.sortJoin(build, "\n", "\t", false);
// key1 value1
// key2 null
// key3 value3
Console.log(join1);
String join2 = MapUtil.sortJoin(build, "\n", "\t", true);
// key1 value1
// key3 value3
Console.log(join2);
String join3 = MapUtil.sortJoin(build, "\n", "\t", false, "123");
// key1 value1
// key2 null
// key3 value3123
Console.log(join3);
}
@Test
public void getTest() {
BiMap<String, Integer> biMap = new BiMap<>(new HashMap<>());
biMap.put("aaa", 111);
biMap.put("bbb", 222);
// 111
Console.log(biMap.get("aaa"));
// bbb
Console.log(biMap.getKey(222));
}
数学相关-MathUtil
此工具是NumberUtil的一个补充,NumberUtil偏向于简单数学计算的封装,MathUtil偏向复杂数学计算。
如排列组合的计算
@Test
public void arrangementCount() {
// A 4 4
long result = MathUtil.arrangementCount(4);
Console.log(result);
}
@Test
public void arrangementSelect() {
// A 4 2
List<String[]> result = MathUtil.arrangementSelect(new String[]{"1", "2", "3", "4"}, 2);
Console.log(result.size());
}
@Test
public void combinationCount() {
// C 4 4
long result = MathUtil.combinationCount(4, 4);
Console.log(result);
}
@Test
public void combinationSelect() {
// C 4 2
List<String[]> result = MathUtil.combinationSelect(new String[]{"1", "2", "3", "4"}, 2);
Console.log(result.size());
}
@Test
public void calculate() {
double conversion = Calculator.conversion("(0*1--3)-5/-4-(3*(-2.13))");
Console.log(conversion);
}
网络工具-NetUtil
@Test
public void getLocalhostStrTest() {
String localhost = NetUtil.getLocalhostStr();
Console.log(localhost);
}
@Test
public void getLocalhostTest() {
InetAddress localhost = NetUtil.getLocalhost();
Console.log(localhost);
}
@Test
public void getLocalMacAddressTest() {
String macAddress = NetUtil.getLocalMacAddress();
Console.log(macAddress);
}
@Test
public void urlEncode() {
String encode = FormUrlencoded.ALL.encode("https://www.baidu.com?token=1&key=2", CharsetUtil.CHARSET_UTF_8);
Console.log(encode);
}
@Test
public void urlDecode() {
String decode = URLDecoder.decodeForPath("https%3A%2F%2Fwww.baidu.com%3Ftoken%3D1%26key%3D2", CharsetUtil.CHARSET_UTF_8);
Console.log(decode);
}
文本处理工具类
CSV 处理工具类
@Test
public void readTest() {
CsvReader reader = CsvUtil.getReader();
CsvData data = reader.read(ResourceUtil.getReader("text/test.csv", CharsetUtil.CHARSET_UTF_8));
List<CsvRow> rows = data.getRows();
for (CsvRow row : rows) {
Console.log(row.getRawList());
}
}
@Test
public void readTest2() {
CsvReader reader = CsvUtil.getReader();
List<User> list = reader.read(ResourceUtil.getUtf8Reader("text/test_user.csv"), User.class);
for (User user : list) {
Console.log(user);
}
}
@Test
public void writeWithAliasTest() {
CsvWriteConfig csvWriteConfig = CsvWriteConfig.defaultConfig()
.addHeaderAlias("name", "姓名")
.addHeaderAlias("gender", "性别")
.addHeaderAlias("address", "地址");
CsvWriter writer = CsvUtil.getWriter(
FileUtil.file("C:\\Users\\fanzh23\\Desktop\\csv\\out.csv"),
CharsetUtil.CHARSET_GBK, false, csvWriteConfig);
writer.writeHeaderLine("name", "gender", "address");
writer.writeLine("张三", "男", "XX市XX区");
writer.writeLine("李四", "男", "XX市XX区,01号");
writer.close();
}
@Test
public void writeTest() {
CsvWriter writer = CsvUtil.getWriter(
FileUtil.file("C:\\Users\\fanzh23\\Desktop\\csv\\out_bean.csv"),
CharsetUtil.CHARSET_GBK, false);
List<User> list = new ArrayList<>();
User student1 = new User();
student1.setId(1);
student1.setName("张三");
student1.setAge(18);
student1.setGender("男");
User student2 = new User();
student2.setId(2);
student2.setName("李四");
student2.setAge(22);
student2.setGender("女");
User student3 = new User();
student3.setId(3);
student3.setName("王五");
student3.setAge(31);
student3.setGender("男");
list.add(student1);
list.add(student2);
list.add(student3);
writer.writeBeans(list);
writer.close();
}
public class User {
private Integer id;
private String name;
private Integer age;
@Alias("性别")
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
unicode 处理工具类
@Test
public void convertTest() {
String s = UnicodeUtil.toUnicode("aaa123中文", true);
// "aaa123\\u4e2d\\u6587"
Console.log(s);
String s1 = UnicodeUtil.toString(s);
// "aaa123中文"
Console.log(s1);
}
线程工具-ThreadUtil
@Test
public void executeTest() {
ThreadUtil.execute(() -> Console.log("hello world"));
ThreadUtil.safeSleep(1000);
}
@Test
public void scheduleTest() {
ThreadUtil.schedule(null, () -> {
Console.log("hello world");
}, 0, 1, TimeUnit.SECONDS, true);
ThreadUtil.safeSleep(2000);
}
@Test
public void asyncTest() throws ExecutionException, InterruptedException {
Future<?> future = ThreadUtil.execAsync(() -> {
Console.log("hello world");
return "hello world";
});
ThreadUtil.safeSleep(2000);
Console.log(future.get());
}
@Test
public void testTest() {
ConcurrencyTester tester = ThreadUtil.concurrencyTest(100, () -> {
// 测试的逻辑内容
long delay = RandomUtil.randomLong(100, 1000);
ThreadUtil.sleep(delay);
Console.log("{} test finished, delay: {}", Thread.currentThread().getName(), delay);
});
// 获取总的执行时间,单位毫秒
Console.log(tester.getInterval());
}
其他工具类
数组工具
@Test
public void isEmptyTest() {
int[] a = {};
Console.log(ArrayUtil.isEmpty(a));
int[] b = null;
Console.log(ArrayUtil.isEmpty(b));
}
@Test
public void newArrayTest() {
String[] newArray = ArrayUtil.newArray(String.class, 3);
Console.log(newArray);
}
@Test
public void rangeTest() {
int[] range = ArrayUtil.range(0, 10);
Assert.assertEquals(0, range[0]);
Assert.assertEquals(1, range[1]);
Assert.assertEquals(2, range[2]);
Assert.assertEquals(3, range[3]);
Assert.assertEquals(4, range[4]);
Assert.assertEquals(5, range[5]);
Assert.assertEquals(6, range[6]);
Assert.assertEquals(7, range[7]);
Assert.assertEquals(8, range[8]);
Assert.assertEquals(9, range[9]);
}
@Test
public void zipTest() {
String[] keys = {"a", "b", "c"};
Integer[] values = {1, 2, 3};
Map<String, Integer> map = ArrayUtil.zip(keys, values, true);
Console.log(map);
}
类工具-ClassUtil
@Test
public void getClassNameTest() {
String className = ClassUtil.getClassName(ClassUtil.class, false);
Console.log(className);
String simpleClassName = ClassUtil.getClassName(ClassUtil.class, true);
Console.log(simpleClassName);
}
@Test
public void getPublicMethod() {
Method superPublicMethod = ClassUtil.getPublicMethod(TestSubClass.class, "publicMethod");
Console.log(superPublicMethod);
Method superPrivateMethod = ClassUtil.getDeclaredMethod(TestSubClass.class, "privateMethod");
// 私有方法
Console.log(superPrivateMethod);
Method publicMethod = ClassUtil.getPublicMethod(TestSubClass.class, "publicSubMethod");
Console.log(publicMethod);
Method privateMethod = ClassUtil.getDeclaredMethod(TestSubClass.class, "privateSubMethod");
Console.log(privateMethod);
}
@Test
public void getDeclaredField() {
// 不存在的字段
Field noField = ClassUtil.getDeclaredField(TestSubClass.class, "noField");
Console.log(noField);
// 获取不到父类字段
Field field = ClassUtil.getDeclaredField(TestSubClass.class, "field");
Console.log(field);
Field subField = ClassUtil.getDeclaredField(TestSubClass.class, "subField");
Console.log(subField);
}
@Test
public void getClassPathTest() {
String classPath = ClassUtil.getClassPath();
Console.log(classPath);
}
@Test
public void getShortClassNameTest() {
String className = "cn.hutool.core.util.StrUtil";
String result = ClassUtil.getShortClassName(className);
// c.h.c.u.StrUtil
Console.log(result);
}
@Test
public void getLocationPathTest() {
String classDir = ClassUtil.getLocationPath(ClassUtilTest.class);
Console.log(classDir);
}
坐标系工具类
@Test
public void wgs84ToGcj02Test(){
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.wgs84ToGcj02(116.404, 39.915);
Assert.assertEquals(116.41033392216508D, coordinate.getLng(), 0);
Assert.assertEquals(39.91640428150164D, coordinate.getLat(), 0);
}
@Test
public void gcj02ToWgs84Test(){
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.gcj02ToWgs84(116.404, 39.915);
Assert.assertEquals(116.39766607783491D, coordinate.getLng(), 0);
Assert.assertEquals(39.91359571849836D, coordinate.getLat(), 0);
}
@Test
public void wgs84toBd09Test(){
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.wgs84ToBd09(116.404, 39.915);
Assert.assertEquals(116.41671695444782D, coordinate.getLng(), 0);
Assert.assertEquals(39.922698713521726D, coordinate.getLat(), 0);
}
@Test
public void bd09toWgs84Test(){
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.bd09toWgs84(116.404, 39.915);
Assert.assertEquals(116.39129143419822D, coordinate.getLng(), 0);
Assert.assertEquals(39.907253214522164D, coordinate.getLat(), 0);
}
@Test
public void gcj02ToBd09Test() {
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.gcj02ToBd09(116.404, 39.915);
Assert.assertEquals(116.41036949371029D, coordinate.getLng(), 0);
Assert.assertEquals(39.92133699351022D, coordinate.getLat(), 0);
}
@Test
public void bd09toGcj02Test(){
final CoordinateUtil.Coordinate coordinate = CoordinateUtil.bd09ToGcj02(116.404, 39.915);
Assert.assertEquals(116.39762729119315D, coordinate.getLng(), 0);
Assert.assertEquals(39.90865673957631D, coordinate.getLat(), 0);
}
社会信用代码工具-CreditCodeUtil
- 第一部分:登记管理部门代码1位 (数字或大写英文字母)
- 第二部分:机构类别代码1位 (数字或大写英文字母)
- 第三部分:登记管理机关行政区划码6位 (数字)
- 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
- 第五部分:校验码1位 (数字或大写英文字母)
@Test
public void isCreditCodeBySimple() {
String testCreditCode = "91310115591693856A";
Assert.assertTrue(CreditCodeUtil.isCreditCodeSimple(testCreditCode));
}
@Test
public void isCreditCode() {
String testCreditCode = "91310110666007217T";
Assert.assertTrue(CreditCodeUtil.isCreditCode(testCreditCode));
}
@Test
public void isCreditCode2() {
// 由于早期部分试点地区推行 法人和其他组织统一社会信用代码 较早,会存在部分代码不符合国家标准的情况。
// 见:https://github.com/bluesky335/IDCheck
String testCreditCode = "91350211M00013FA1N";
Assert.assertFalse(CreditCodeUtil.isCreditCode(testCreditCode));
}
@Test
public void randomCreditCode() {
final String s = CreditCodeUtil.randomCreditCode();
Assert.assertTrue(CreditCodeUtil.isCreditCode(s));
}
信息脱敏工具-DesensitizedUtil
@Test
public void desensitizedTest() {
Assert.assertEquals("0", DesensitizedUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID));
Assert.assertEquals("段**", DesensitizedUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME));
Assert.assertEquals("5***************1X", DesensitizedUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD));
Assert.assertEquals("0915*****79", DesensitizedUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE));
Assert.assertEquals("180****1999", DesensitizedUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
Assert.assertEquals("北京市海淀区马********", DesensitizedUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS));
Assert.assertEquals("d*************@gmail.com.cn", DesensitizedUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL));
Assert.assertEquals("**********", DesensitizedUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD));
Assert.assertEquals("0", DesensitizedUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID));
Assert.assertEquals("段**", DesensitizedUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME));
Assert.assertEquals("5***************1X", DesensitizedUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD));
Assert.assertEquals("0915*****79", DesensitizedUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE));
Assert.assertEquals("180****1999", DesensitizedUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
Assert.assertEquals("北京市海淀区马********", DesensitizedUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS));
Assert.assertEquals("d*************@gmail.com.cn", DesensitizedUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL));
Assert.assertEquals("**********", DesensitizedUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD));
Assert.assertEquals("1101 **** **** **** 3256", DesensitizedUtil.desensitized("11011111222233333256", DesensitizedUtil.DesensitizedType.BANK_CARD));
Assert.assertEquals("6227 **** **** *** 5123", DesensitizedUtil.desensitized("6227880100100105123", DesensitizedUtil.DesensitizedType.BANK_CARD));
}
@Test
public void userIdTest() {
Assert.assertEquals(Long.valueOf(0L), DesensitizedUtil.userId());
}
@Test
public void chineseNameTest() {
Assert.assertEquals("段**", DesensitizedUtil.chineseName("段正淳"));
}
@Test
public void idCardNumTest() {
Assert.assertEquals("5***************1X", DesensitizedUtil.idCardNum("51343620000320711X", 1, 2));
}
@Test
public void fixedPhoneTest() {
Assert.assertEquals("0915*****79", DesensitizedUtil.fixedPhone("09157518479"));
}
@Test
public void mobilePhoneTest() {
Assert.assertEquals("180****1999", DesensitizedUtil.mobilePhone("18049531999"));
}
@Test
public void addressTest() {
Assert.assertEquals("北京市海淀区马连洼街*****", DesensitizedUtil.address("北京市海淀区马连洼街道289号", 5));
Assert.assertEquals("***************", DesensitizedUtil.address("北京市海淀区马连洼街道289号", 50));
Assert.assertEquals("北京市海淀区马连洼街道289号", DesensitizedUtil.address("北京市海淀区马连洼街道289号", 0));
Assert.assertEquals("北京市海淀区马连洼街道289号", DesensitizedUtil.address("北京市海淀区马连洼街道289号", -1));
}
@Test
public void emailTest() {
Assert.assertEquals("d********@126.com", DesensitizedUtil.email("duandazhi@126.com"));
Assert.assertEquals("d********@gmail.com.cn", DesensitizedUtil.email("duandazhi@gmail.com.cn"));
Assert.assertEquals("d*************@gmail.com.cn", DesensitizedUtil.email("duandazhi-jack@gmail.com.cn"));
}
@Test
public void passwordTest() {
Assert.assertEquals("**********", DesensitizedUtil.password("1234567890"));
}
@Test
public void carLicenseTest() {
Assert.assertEquals("", DesensitizedUtil.carLicense(null));
Assert.assertEquals("", DesensitizedUtil.carLicense(""));
Assert.assertEquals("苏D4***0", DesensitizedUtil.carLicense("苏D40000"));
Assert.assertEquals("陕A1****D", DesensitizedUtil.carLicense("陕A12345D"));
Assert.assertEquals("京A123", DesensitizedUtil.carLicense("京A123"));
}
枚举工具类 EnumUtil
@Test
public void getNamesTest() {
List<String> names = EnumUtil.getNames(TestEnum.class);
// [TEST1, TEST2, TEST3]
Console.log(names);
}
@Test
public void getFieldValuesTest() {
List<Object> types = EnumUtil.getFieldValues(TestEnum.class, "type");
// [type1, type2, type3]
Console.log(types);
}
@Test
public void getFieldNamesTest() {
List<String> names = EnumUtil.getFieldNames(TestEnum.class);
// [type, name]
Console.log(names);
}
@Test
public void getByTest() {
// 枚举中字段互相映射使用
TestEnum testEnum = EnumUtil.getBy(TestEnum::ordinal, 2);
// type3
Console.log(testEnum.getType());
}
@Test
public void getFieldByTest() {
// 枚举中字段互相映射使用
String type = EnumUtil.getFieldBy(TestEnum::getType, Enum::ordinal, 2);
// type3
Console.log(type);
}
@Test
public void getEnumMapTest() {
Map<String, TestEnum> enumMap = EnumUtil.getEnumMap(TestEnum.class);
// {TEST1=TEST1, TEST2=TEST2, TEST3=TEST3}
Console.log(enumMap);
}
@Test
public void getNameFieldMapTest() {
Map<String, Object> enumMap = EnumUtil.getNameFieldMap(TestEnum.class, "type");
// {TEST1=type1, TEST2=type2, TEST3=type3}
Console.log(enumMap);
}
Escape工具-EscapeUtil
@Test
public void escapeTest() {
String str = "*@-_+./(123你好)ABCabc";
String escape = EscapeUtil.escape(str);
// *@-_+./%28123%u4f60%u597d%29ABCabc
Console.log(escape);
String unescape = EscapeUtil.unescape(escape);
// *@-_+./(123你好)ABCabc
Console.log(unescape);
}
@Test
public void escapeAllTest() {
String str = "*@-_+./(123你好)ABCabc";
String escape = EscapeUtil.escapeAll(str);
// %2a%40%2d%5f%2b%2e%2f%28%31%32%33%u4f60%u597d%29%41%42%43%61%62%63
Console.log(escape);
String unescape = EscapeUtil.unescape(escape);
// *@-_+./(123你好)ABCabc
Console.log(unescape);
}
Hash算法-HashUtil
HashUtil其实是一个hash算法的集合,此工具类中融合了各种hash算法。
- additiveHash 加法hash
- rotatingHash 旋转hash
- oneByOneHash 一次一个hash
- bernstein Bernstein's hash
- universal Universal Hashing
- zobrist Zobrist Hashing
- fnvHash 改进的32位FNV算法1
- intHash Thomas Wang的算法,整数hash
- rsHash RS算法hash
- jsHash JS算法
- pjwHash PJW算法
- elfHash ELF算法
- bkdrHash BKDR算法
- sdbmHash SDBM算法
- djbHash DJB算法
- dekHash DEK算法
- apHash AP算法
- tianlHash TianL Hash算法
- javaDefaultHash JAVA自己带的算法
- mixHash 混合hash算法,输出64位的值
16进制工具-HexUtil
@Test
public void hexStrTest() {
String str = "hello world";
String hex = HexUtil.encodeHexStr(str, CharsetUtil.CHARSET_UTF_8);
Console.log(hex);
String decodedStr = HexUtil.decodeHexStr(hex);
Console.log(decodedStr);
}
身份证工具-IdcardUtil
private static final String ID_18 = "321083197812162119";
private static final String ID_15 = "150102880730303";
@Test
public void isValidCardTest() {
boolean valid = IdcardUtil.isValidCard(ID_18);
Console.log(valid);
boolean valid15 = IdcardUtil.isValidCard(ID_15);
Console.log(valid15);
String invalidIdCard = "360198910283844";
Console.log(IdcardUtil.isValidCard(invalidIdCard));
}
@Test
public void convertTest() {
String convert15To18 = IdcardUtil.convert15To18(ID_15);
Console.log(convert15To18);
String convert15To18Second = IdcardUtil.convert15To18("330102200403064");
Console.log(convert15To18Second);
}
@Test
public void getAgeByIdCardTest() {
DateTime date = DateUtil.parse("2022-11-07");
int age = IdcardUtil.getAgeByIdCard(ID_18, date);
Console.log(age);
}
@Test
public void getBirthByIdCardTest() {
String birth = IdcardUtil.getBirthByIdCard(ID_18);
Console.log(birth);
}
@Test
public void getProvinceByIdCardTest() {
String province = IdcardUtil.getProvinceByIdCard(ID_18);
Console.log(province);
}
@Test
public void getGenderByIdCardTest() {
int gender = IdcardUtil.getGenderByIdCard(ID_18);
// 17位 奇数位男性,偶数位女性
Console.log(gender);
}
唯一ID工具-IdUtil
@Test
public void randomUUIDTest() {
String randomUUID = IdUtil.randomUUID();
Console.log(randomUUID);
String simpleUUID = IdUtil.simpleUUID();
Console.log(simpleUUID);
}
@Test
public void objectIdTest() {
String objectId = IdUtil.objectId();
Console.log(objectId);
}
@Test
public void snowflakeTest() {
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id = snowflake.nextId();
Console.log(id);
// 简单使用
long snowflakeNextId = IdUtil.getSnowflakeNextId();
Console.log(snowflakeNextId);
}
@Test
public void snowflakeBenchTest() {
final Set<Long> set = new ConcurrentHashSet<>();
final Snowflake snowflake = IdUtil.getSnowflake(1, 1);
// 线程数
int threadCount = 100;
// 每个线程生成的ID数
final int idCountPerThread = 10000;
final CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
ThreadUtil.execute(() -> {
for (int i1 = 0; i1 < idCountPerThread; i1++) {
long id = snowflake.nextId();
set.add(id);
}
latch.countDown();
});
}
// 等待全部线程结束
try {
latch.await();
} catch (InterruptedException e) {
throw new UtilException(e);
}
Console.log("{},{}", threadCount * idCountPerThread, set.size());
}
/**
* 性能测试
*/
@Test
public void benchTest() {
int num = 10000000;
TimeInterval timer = DateUtil.timer();
for (int i = 0; i < num; i++) {
UUID.randomUUID().toString().replace("-", "");
}
Console.log("jdk 的 uuid 生成:{}ms", timer.interval());
timer.restart();
for (int i = 0; i < num; i++) {
IdUtil.simpleUUID();
}
Console.log("自定义 uuid 生成:{}ms", timer.interval());
timer.restart();
for (int i = 0; i < num; i++) {
IdUtil.objectId();
}
Console.log("objectId 生成:{}ms", timer.interval());
timer.restart();
for (int i = 0; i < num; i++) {
IdUtil.getSnowflakeNextId();
}
Console.log("雪花算法 生成:{}ms", timer.interval());
}
数字工具类 NumberUtil
@Test
public void addTest() {
Float a = 3.15f;
Double b = 4.22;
double result = NumberUtil.add(a, b).doubleValue();
Console.log(result);
}
@Test
public void divTest() {
double result = NumberUtil.div(0, 1);
Console.log(result);
}
@Test
public void divBigDecimalTest() {
// 四舍五入,保留3位
BigDecimal result = NumberUtil.div(new BigDecimal("1"), new BigDecimal("3"), 3, RoundingMode.HALF_UP);
Console.log(result);
}
@Test
public void roundTest() {
BigDecimal result = NumberUtil.round("2.647", 2, RoundingMode.HALF_UP);
Console.log(result);
}
@Test
public void decimalFormatTest() {
long c = 299792458;
// ,### -> 每三位以逗号进行分隔
String format = NumberUtil.decimalFormat(",###", c);
Console.log(format);
}
@Test
public void range() {
int[] range = NumberUtil.range(1, 10, 2);
for (int i : range) {
Console.log(i);
}
}
对象工具类 ObjectUtil
@Test
public void equalsTest() {
Integer a = 1;
Integer b = 1;
Console.log(ObjectUtil.equal(a, b));
}
@Test
public void lengthTest() {
int[] array = new int[]{1, 2, 3, 4, 5};
int length = ObjectUtil.length(array);
Console.log(length);
Map<String, String> map = new HashMap<>();
map.put("a", "a1");
map.put("b", "b1");
map.put("c", "c1");
length = ObjectUtil.length(map);
Console.log(length);
}
@Test
public void containsTest() {
int[] array = new int[]{1, 2, 3, 4, 5};
boolean contains = ObjectUtil.contains(array, 1);
Console.log(contains);
}
反射工具类 ReflectUtil
@Test
public void getFiledTest() {
Field[] fields = ReflectUtil.getFields(ExamInfoDict.class, field -> field.getName().contains("id"));
for (Field field : fields) {
Console.log(field.getName());
}
}
@Test
public void getMethodsTest() {
Method[] methods = ReflectUtil.getMethods(ExamInfoDict.class, method -> method.getName().contains("get"));
for (Method method : methods) {
Console.log(method.getName());
}
}
@Test
public void getMethodTest() {
Method method = ReflectUtil.getMethod(ExamInfoDict.class, "getId");
Console.log(method.getName());
}
@Test
public void newInstance() {
ExamInfoDict examInfoDict = ReflectUtil.newInstance(ExamInfoDict.class);
Console.log(examInfoDict);
}
@Test
public void invokeTest() {
ExamInfoDict examInfoDict = new ExamInfoDict();
ReflectUtil.invoke(examInfoDict, "setId", 1L);
Object result = ReflectUtil.invoke(examInfoDict, "getId");
Console.log(result);
}
正则工具类
final String content = "ZZZaaabbbccc中文1234";
@Test
public void getTest() {
String resultGet = ReUtil.get("\\w{2}", content, 0);
// ZZ
Console.log(resultGet);
}
@Test
public void extractMultiTest() {
// 抽取多个分组然后把它们拼接起来
String resultExtractMulti = ReUtil.extractMulti("(\\w)aa(\\w)", content, "$1-$2");
// Z-a
Console.log(resultExtractMulti);
}
@Test
public void delFirstTest() {
// 删除第一个匹配到的内容
String resultDelFirst = ReUtil.delFirst("(\\w)aa(\\w)", content);
// ZZbbbccc中文1234
Console.log(resultDelFirst);
}
@Test
public void delAllTest() {
// 删除所有匹配到的内容
String content = "发东方大厦eee![images]http://abc.com/2.gpg]好机会eee![images]http://abc.com/2.gpg]好机会";
String resultDelAll = ReUtil.delAll("!\\[images\\][^\\u4e00-\\u9fa5\\\\s]*", content);
// 发东方大厦eee好机会eee好机会
Console.log(resultDelAll);
}
@Test
public void findAllTest() {
// 查找所有匹配文本
List<String> resultFindAll = ReUtil.findAll("\\w{2}", content, 0, new ArrayList<>());
// [ZZ, Za, aa, bb, bc, cc, 12, 34]
Console.log(resultFindAll);
}
@Test
public void getFirstNumberTest() {
// 找到匹配的第一个数字
Integer resultGetFirstNumber = ReUtil.getFirstNumber(content);
// 1234
Console.log(resultGetFirstNumber);
}
@Test
public void isMatchTest() {
// 给定字符串是否匹配给定正则
boolean isMatch = ReUtil.isMatch("\\w+[\u4E00-\u9FFF]+\\d+", content);
Console.log(isMatch);
}
@Test
public void replaceAllTest() {
//通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串
//此处把1234替换为 ->1234<-
String replaceAll = ReUtil.replaceAll(content, "(\\d+)", "->$1<-");
// ZZZaaabbbccc中文->1234<-
Console.log(replaceAll);
}
@Test
public void getAllGroupsTest() {
//转义给定字符串,为正则相关的特殊符号转义
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)-(\\d+)");
List<String> allGroups = ReUtil.getAllGroups(pattern, "192-168-1-1");
Console.log(allGroups);
allGroups = ReUtil.getAllGroups(pattern, "192-168-1-1", false);
Console.log(allGroups);
}
@Test
public void getAllGroupNamesTest() {
String content = "2021-10-11";
String regex = "(?<year>\\d+)-(?<month>\\d+)-(?<day>\\d+)";
Map<String, String> map = ReUtil.getAllGroupNames(PatternPool.get(regex, Pattern.DOTALL), content);
Console.log(map);
}
命令行工具类 RuntimeUtil
@Test
public void execTest() {
String str = RuntimeUtil.execForStr("ipconfig");
Console.log(str);
}
@Test
public void execCmdTest() {
String str = RuntimeUtil.execForStr("cmd /c dir");
Console.log(str);
}
@Test
public void getUsableMemoryTest() {
Console.log(RuntimeUtil.getUsableMemory());
}
@Test
public void getPidTest() {
int pid = RuntimeUtil.getPid();
Console.log(pid);
}
@Test
public void getProcessorCountTest() {
int cpu = RuntimeUtil.getProcessorCount();
Console.log("cpu个数:{}", cpu);
}
字符串工具类 StrUtil
@Test
public void isBlankTest() {
String blank = " ";
Console.log(StrUtil.isBlank(blank));
}
@Test
public void trimTest() {
String blank = "\r\n\t 哈哈 ";
String trim = StrUtil.trim(blank);
Console.log(trim);
}
@Test
public void cutTest() {
String str = "aaabbbcccdddaadfdfsdfsdf0";
String[] cut = StrUtil.cut(str, 4);
Console.log(cut);
}
@Test
public void splitTest() {
String str = "a,b ,c,d,,e";
List<String> split = StrUtil.split(str, ',', -1, true, true);
// [a, b, c, d, e]
Console.log(split);
List<String> split2 = StrUtil.split(str, ',', -1, true, false);
// [a, b, c, d, , e]
Console.log(split2);
List<String> split3 = StrUtil.split(str, ',', -1, false, true);
// [a, b , c, d, e]
Console.log(split3);
List<String> split4 = StrUtil.split(str, ',');
// [a, b , c, d, , e]
Console.log(split4);
}
@Test
public void formatTest() {
String template = "你好,我是{name},我的电话是:{phone}";
String result = StrUtil.format(template, Dict.create().set("name", "张三").set("phone", "13888881111"));
Console.log(result);
String result2 = StrUtil.format(template, Dict.create().set("name", "张三").set("phone", null));
Console.log(result2);
}
@Test
public void stripTest() {
String str = "abcd123";
String strip = StrUtil.strip(str, "ab", "23");
Console.log(strip);
}
@Test
public void repeatAndJoinTest() {
String repeatAndJoin = StrUtil.repeatAndJoin("?", 5, ",");
Console.log(repeatAndJoin);
}
@Test
public void moveTest() {
String str = "aaaaaaa22222bbbbbbb";
String result = StrUtil.move(str, 7, 12, -3);
Console.log(result);
}
@Test
public void maxLengthTest() {
String text = "我是一段正文,很长的正文,需要截取的正文";
String str = StrUtil.maxLength(text, 5);
Console.log(str);
}
@Test
public void padTest() {
// 001
Console.log(StrUtil.padPre("1", 3, '0'));
// 12
Console.log(StrUtil.padPre("123", 2, '0'));
// 100
Console.log(StrUtil.padAfter("1", 3, '0'));
// 23
Console.log(StrUtil.padAfter("123", 2, '0'));
}
@Test
public void briefTest() {
// case: 1 至 str.length - 1
String str = RandomUtil.randomString(RandomUtil.randomInt(1, 100));
// case: 不会格式化的值
Console.log(StrUtil.brief(str, 10));
Console.log(StrUtil.brief(str, 0));
Console.log(StrUtil.brief(str, -1));
Console.log(StrUtil.brief(str, str.length()));
}
泛型类型工具 TypeUtil
@Test
public void getEleTypeTest() {
Method method = ReflectUtil.getMethod(TypeTestClass.class, "getList", Integer.class);
// 获取入参类型
Type paramType = TypeUtil.getParamType(method, 0);
Console.log(paramType);
// 获取返回值类型
Type returnType = TypeUtil.getReturnType(method);
Console.log(returnType);
// 获取泛型
Type genericType = TypeUtil.getTypeArgument(returnType);
Console.log(genericType);
}
@Test
public void getActualTypesTest() {
// 测试多层级泛型参数是否能获取成功
Type idType = TypeUtil.getActualType(Level3.class,
ReflectUtil.getField(Level3.class, "id"));
Console.log(idType);
}
public static class Level3 extends Level2<Level3> {
}
public static class Level2<E> extends Level1<Long> {
}
// @Data
public static class Level1<T> {
private T id;
}
XML 工具类
@Test
public void readXmlTest() {
Document document = XmlUtil.readXML(ResourceUtil.getReader("util/test.xml", CharsetUtil.CHARSET_UTF_8));
String elementText = XmlUtil.elementText(document.getDocumentElement(), "returnstatus");
Console.log(elementText);
}
@Test
public void parseTest() {
String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"//
+ "<returnstatus>Success</returnstatus>"//
+ "<message>ok</message>"//
+ "<remainpoint>1490</remainpoint>"//
+ "<taskID>885</taskID>"//
+ "<successCounts>1</successCounts>"//
+ "</returnsms>";
Document docResult = XmlUtil.parseXml(result);
String elementText = XmlUtil.elementText(docResult.getDocumentElement(), "returnstatus");
Console.log(elementText);
}
@Test
public void writeTest() {
String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"//
+ "<returnstatus>Success(成功)</returnstatus>"//
+ "<message>ok</message>"//
+ "<remainpoint>1490</remainpoint>"//
+ "<taskID>885</taskID>"//
+ "<successCounts>1</successCounts>"//
+ "</returnsms>";
Document docResult = XmlUtil.parseXml(result);
XmlUtil.toFile(docResult, "C:\\Users\\fanzh23\\Desktop\\hutool\\test.xml", "utf-8");
}
@Test
public void xpathTest() {
Document document = XmlUtil.readXML(ResourceUtil.getReader("util/test.xml", CharsetUtil.CHARSET_UTF_8));
Object value = XmlUtil.getByXPath("/returnsms/message", document, XPathConstants.STRING);
Console.log(value);
}
@Test
public void xmlToMapTest() {
Document document = XmlUtil.readXML(ResourceUtil.getReader("util/test.xml", CharsetUtil.CHARSET_UTF_8));
String xml = XmlUtil.toStr(document);
Map<String, Object> map = XmlUtil.xmlToMap(xml);
Console.log(map);
}
@Test
public void mapToXmlTest() {
Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>())//
.put("name", "张三")//
.put("age", 12)//
.put("game", MapUtil.builder(new LinkedHashMap<String, Object>()).put("昵称", "Looly").put("level", 14).build())//
.build();
Document doc = XmlUtil.mapToXml(map, "user");
Console.log(XmlUtil.format(doc));
}