Java学习笔记 - Hutool

编码工具

16进制工具

TestHex.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.awt.Color;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestHex {
@Test
@Comment("判断是否是十六进制")
public void test1() {

String s1 = "12";
boolean b1 = HexUtil.isHexNumber(s1);
String s2 = "0x12";
boolean b2 = HexUtil.isHexNumber(s2);

p2("字符串",s1, "是否十六机制",b1);
p2("字符串",s2, "是否十六机制",b2);

}
@Test
@Comment("字符串和十六进制互相转换")
public void test2() {

String s1 = "how2j.cn - java教程";
String s2 = HexUtil.encodeHexStr(s1);
String s3 = HexUtil.decodeHexStr(s2);

p2("原数据",s1, "十六机制编码",s2);
p2("十六进制",s2, "十六机制解码",s3);

}
@Test
@Comment("颜色转换")
public void test3() {

Color color1 = Color.red;
String s1 = HexUtil.encodeColor(color1);
String s2 = "#112233";
Color color2 = HexUtil.decodeColor(s2);
p2("颜色对象1",color1, "字符串",s1);
p2("字符串",s2, "颜色对象2",color2);

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

转义工具

TestEscape.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.EscapeUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestEscape {
@Test
@Comment("转义与反转义")
public void test2() {
String s1 = "<script>location.href='http://how2j.cn';</script>";
String s2 = EscapeUtil.escapeHtml4(s1);
String s3 = EscapeUtil.unescapeHtml4(s2);

p2("原数据",s1, "转义后",s2);
p2("转义后",s2, "原数据",s3);

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

Hash工具

TestHash.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.HashUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestHash {
@Test
@Comment("各种各样的hash算法")
public void test2() {
String s = "how2j.cn- java教程";
int number = 12;
long hash1 = HashUtil.additiveHash(s, Integer.MAX_VALUE);
long hash2 = HashUtil.rotatingHash(s, Integer.MAX_VALUE);
long hash3 = HashUtil.oneByOneHash(s);
long hash4 = HashUtil.bernstein(s);
// long hash5 = HashUtil.universal(s); 怎么调用?站长不会调用。。。颜面~~~
// long hash6 = HashUtil.zobrist(s);
long hash7 = HashUtil.fnvHash(s);
long hash8 = HashUtil.intHash(number);
long hash9 = HashUtil.rsHash(s);
long hash10 = HashUtil.jsHash(s);
long hash11 = HashUtil.pjwHash(s);
long hash12 = HashUtil.elfHash(s);
long hash13 = HashUtil.bkdrHash(s);
long hash14 = HashUtil.sdbmHash(s);
long hash15 = HashUtil.djbHash(s);
long hash16 = HashUtil.dekHash(s);
long hash17 = HashUtil.apHash(s);
long hash18 = HashUtil.tianlHash(s);
long hash19 = HashUtil.javaDefaultHash(s);
long hash20 = HashUtil.mixHash(s);
p2("原数据",s, "加法算法对应的哈希值", hash1);
p2("原数据",s, "旋转算法对应的哈希值", hash2);
p2("原数据",s, "一次一个算法对应的哈希值", hash3);
p2("原数据",s, "Bernstein's算法对应的哈希值", hash4);
// p2("原数据",s, " Universal 算法对应的哈希值", hash5);
// p2("原数据",s, " Zobrist 算法对应的哈希值", hash6);
p2("原数据",s, " 改进的32位FNV 算法对应的哈希值", hash7);
p2("原数据",s, "Thomas Wang的整数算法对应的哈希值", hash8);
p2("原数据",s, "RS算法对应的哈希值", hash9);
p2("原数据",s, "JS算法对应的哈希值", hash10);
p2("原数据",s, "PJ算法对应的哈希值", hash11);
p2("原数据",s, "ELF算法对应的哈希值", hash12);
p2("原数据",s, "BKDR算法对应的哈希值", hash13);
p2("原数据",s, "SDBM算法对应的哈希值", hash14);
p2("原数据",s, "DJB算法对应的哈希值", hash15);
p2("原数据",s, "DEK算法对应的哈希值", hash16);
p2("原数据",s, "AP算法对应的哈希值", hash17);
p2("原数据",s, "TianL算法对应的哈希值", hash18);
p2("原数据",s, "JAVA自己带算法对应的哈希值", hash19);
p2("原数据",s, "混合算法对应的哈希值", hash20);

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

URL工具

TestURL.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;

public class TestURL {

@Test
@Comment("URLUtil使用举例")
public void test1() {
String url1 = "how2j.cn";
String url2 = "http://how2j.cn/k/tmall_springboot/tmall_springboot-1799/1799.html";
String urla =URLUtil.formatUrl(url1);
String urlb = URLUtil.encode(url2);
String urlc = URLUtil.decode(urlb);
String urld = URLUtil.getPath(url2);

p1("原数据",url1, "格式化之后",urla);
p1("原数据",url2, "编码数据",urlb);
p1("编码数据",urlb, "解码数据",urlc);
p1("原数据",url2, "对应路径路径",urld);

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

Base32-64工具

TestIdBase32_64.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.codec.Base32;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestIdBase32_64 {

@Test
@Comment("base-32-64转换")
public void test1() {
String charset = "utf-8";

String content = "how2j.cn - java教程";

p3("原字符串",content);

String code32= Base32.encode(content, charset);
content = Base32.decodeStr(code32,charset);

p3("32位编码后",code32);
p3("32位解码",content);

String code64= Base64.encode(content, charset);
content = Base64.decodeStr(code64,charset);
p3("64位编码后",code64);
p3("64位解码",content);

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({ METHOD, TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

Unicode工具

TestUnicode.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestUnicode {
@Test
@Comment("unicode转换")
public void test1() {
String charset = "utf-8";

String content = "how2j.cn - java教程";

p3("原字符串",content);

String unicode= UnicodeUtil.toUnicode(content);
content = UnicodeUtil.toString(unicode);

p3("获取unicode",unicode);
p3("转会原字符串",content);

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({ METHOD, TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

常用辅助类工具

转换工具

TestConverter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.List;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestConverter {

@Test
@Comment("转换为字符串")
public void test1() {
int a = 1;
String aStr = Convert.toStr(a);

int[] b = {1, 2, 3, 4, 5};
String bStr = Convert.toStr(b);

Object c = null;
String cStr = Convert.toStr(c, "空字符串(默认值)");

p("整数", a, "字符串", aStr);
p("long数组", b, "字符串", bStr);
p("空对象", c, "字符串", cStr);

}

@Test
@Comment("数组类型互相转化")
public void test2() {
String[] a = {"1", "2", "3", "4"};
Integer[] b = Convert.toIntArray(a);
p("字符串数组", Convert.toStr(a), "Integer数组", Convert.toStr(b));
}

@Test
@Comment("数组和集合互换")

public void test3() {

String[] a = {"1", "2", "3", "4"};

List<?> l = Convert.toList(a);

String[] b = Convert.toStrArray(l);
p("字符串数组", a, "集合", l);
p("集合", l, "字符串数组", b);
}

@Test
@Comment("半角全角互相转换")
public void test4() {
String a = "123456789";
String b = Convert.toSBC(a);
String c = Convert.toDBC(b);
p("半角", a, "全角", b);
p("全角", b, "半角", c);
}

@Test
@Comment("Unicode和字符串转换")
public void test6() {
String a = "how2j的Hutool教程";
String unicode = Convert.strToUnicode(a);
String b = Convert.unicodeToStr(unicode);

p("字符串", a, "unicode", unicode);
p("unicode", unicode, "字符串", b);

}

@Test
@Comment("不同编码之间的转换")
public void test7() {
String a = "how2j的Hutool教程";
//转换后result为乱码
String b = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
String c = Convert.convertCharset(b, CharsetUtil.ISO_8859_1, "UTF-8");

p("UTF-8", a, "ISO-8859-1", b);
p("ISO-8859-1", b, "UTF-8", c);
}

@Test
@Comment("数字转换为金额")
public void test8() {
double a = 1234567123456.12;
String b = Convert.digitToChinese(a);
p("数字", a, "钞票金额", b);
}

@Test
@Comment("原始类和包装类转换")
public void test9() {
Class<?> wrapClass = Integer.class;

Class<?> unWraped = Convert.unWrap(wrapClass);

Class<?> primitiveClass = long.class;

Class<?> wraped = Convert.wrap(primitiveClass);
p("包装类型", wrapClass, "原始类型", unWraped);
p("原始类型", primitiveClass, "wraped", wraped);
}

private String preComment = null;

private void p(String type1, Object value1, String type2, Object value2) {
try {
throw new Exception();
} catch (Exception e) {
String methodName = e.getStackTrace()[1].getMethodName();
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s :\t\"%s\" %n%n", type1, value1, type2, value2);
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

日期工具

TestDate.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Date;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.BetweenFormater.Level;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestDate {
@Test
@Comment("字符串转日期")
public void test0() {
printDefaultFormat();
Date d;
String str3 = "12:12:12";
d = DateUtil.parse(str3);
p1("字符串", str3, "日期格式", d);

String str1 = "2012-12-12";
d = DateUtil.parse(str1);
p1("字符串", str1, "日期格式", d);

String str4 = "2012-12-12 12:12";
d = DateUtil.parse(str4);
p1("字符串", str4, "日期格式", d);

String str2 = "2012-12-12 12:12:12";
d = DateUtil.parse(str2);
p1("字符串", str2, "日期格式", d);
}

@Test
@Comment("日期转字符串")
public void test1() {
Date d = new Date();

//结果 2017/03/01
String format = DateUtil.format(d, "yyyy/MM/dd");

//常用格式的格式化,结果:2017-03-01
String formatDate = DateUtil.formatDate(d);

//结果:2017-03-01 00:00:00
String formatDateTime = DateUtil.formatDateTime(d);

//结果:00:00:00
String formatTime = DateUtil.formatTime(d);

p1("日期格式", d, "自定义格式的字符串", format);
p1("日期格式", d, "只是日期格式", formatDate);
p1("日期格式", d, "日期和时间格式", formatDateTime);
p1("日期格式", d, "只是时间格式", formatTime);
}

@Test
@Comment("获取部分信息")
public void test2() {
Date d = new Date();
//获得年的部分
int year = DateUtil.year(d);
//获得月份,从0开始计数
int month = DateUtil.month(d);
//获得月份枚举
Enum months = DateUtil.monthEnum(d);

p2("当前日期", DateUtil.formatDateTime(d), "年份", year);
p2("当前日期", DateUtil.formatDateTime(d), "月份", month);
p2("当前日期", DateUtil.formatDateTime(d), "月份枚举信息", months);

}

@Test
@Comment("开始和结束时间")
public void test3() {
Date date = new Date();

//一天的开始,结果:2017-03-01 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);

//一天的结束,结果:2017-03-01 23:59:59
Date endOfDay = DateUtil.endOfDay(date);
p2("当前日期", DateUtil.formatDateTime(date), "开始时间", beginOfDay);
p2("当前日期", DateUtil.formatDateTime(date), "结束时间", endOfDay);
c("这个在查询数据库时,根据日期查一个范围内的数据就很有用");
}

@Test
@Comment("日期时间偏移")
public void test4() {
Date date = new Date();

Date d1 = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);

Date d2 = DateUtil.offsetDay(date, 3);

Date d3 = DateUtil.offsetHour(date, -3);

p2("当前日期", DateUtil.formatDateTime(date), "两天之后的日期", d1);
p2("当前日期", DateUtil.formatDateTime(date), "三天之后的日期", d2);
p2("当前日期", DateUtil.formatDateTime(date), "三小时之前的日期", d3);

}

@Test
@Comment("偏移简化用法")
public void test5() {
Date date = new Date();
Date d1 = DateUtil.yesterday();
Date d2 = DateUtil.tomorrow();
Date d3 = DateUtil.lastWeek();
Date d4 = DateUtil.nextWeek();
Date d5 = DateUtil.lastMonth();
Date d6 = DateUtil.nextMonth();
p2("当前日期", DateUtil.formatDateTime(date), "昨天", d1);
p2("当前日期", DateUtil.formatDateTime(date), "明天", d2);
p2("当前日期", DateUtil.formatDateTime(date), "上周", d3);
p2("当前日期", DateUtil.formatDateTime(date), "下周", d4);
p2("当前日期", DateUtil.formatDateTime(date), "上个月", d5);
p2("当前日期", DateUtil.formatDateTime(date), "下个月", d6);

}

@Test
@Comment("日期时间差")
public void test6() {
Date date1 = DateUtil.parse("2012-12-12 12:12:12");
Date date2 = DateUtil.parse("2013-13-13 13:13:13");

long b1 = DateUtil.between(date1, date2, DateUnit.MS);
long b2 = DateUtil.between(date1, date2, DateUnit.SECOND);
long b3 = DateUtil.between(date1, date2, DateUnit.MINUTE);
long b4 = DateUtil.between(date1, date2, DateUnit.HOUR);
long b5 = DateUtil.between(date1, date2, DateUnit.DAY);
long b6 = DateUtil.between(date1, date2, DateUnit.WEEK);

p2("当前如下两个日期", date1 + " " + date2, "相差毫秒", b1);
p2("当前如下两个日期", date1 + " " + date2, "相差秒", b2);
p2("当前如下两个日期", date1 + " " + date2, "相差分", b3);
p2("当前如下两个日期", date1 + " " + date2, "相差小时", b4);
p2("当前如下两个日期", date1 + " " + date2, "相差天", b5);
p2("当前如下两个日期", date1 + " " + date2, "相差星期", b6);
}

@Test
@Comment("格式化时间差")
public void test7() {
long between = System.currentTimeMillis();

String s0 = DateUtil.formatBetween(between, Level.MILLSECOND);
String s1 = DateUtil.formatBetween(between, Level.SECOND);
String s2 = DateUtil.formatBetween(between, Level.MINUTE);
String s3 = DateUtil.formatBetween(between, Level.HOUR);
String s4 = DateUtil.formatBetween(between, Level.DAY);
p2("毫秒数", between, "对应时间,精度到毫秒", s0);
p2("毫秒数", between, "对应时间,精度到秒", s1);
p2("毫秒数", between, "对应时间,精度到秒分钟", s2);
p2("毫秒数", between, "对应时间,精度到秒小时", s3);
p2("毫秒数", between, "对应时间,精度到秒天", s4);

}

@Test
@Comment("性能统计")
public void test8() {
int loopcount = 100;
TimeInterval timer = DateUtil.timer();
forloop(loopcount);
long interval1 = timer.interval();
forloop(loopcount);
long interval2 = timer.intervalRestart();
forloop(loopcount);
long interval3 = timer.interval();

p3("性能统计,总共花费了 (毫秒数)", interval1);
p3("性能统计,总共花费了 (毫秒数),并重置", interval2);
p3("性能统计,总共花费了 (毫秒数)", interval3);

}

@Test
@Comment("其他")
public void test9() {

String birthDay = "1949-10-01";
int age = DateUtil.ageOfNow(birthDay);

int year = 2012;
boolean isLeap = DateUtil.isLeapYear(year);

String now = DateUtil.now();
String today = DateUtil.today();

p2("生日", birthDay, "年龄", age);
p2("年份", year, "是否闰年", isLeap);

p3("现在", now);
p3("今天", today);

}

private void forloop(int total) {
for (int i = 0; i < total; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public void printDefaultFormat() {
System.out.println("DateUtil默认会对如下格式进行识别:");
System.out.println();

System.out.println("\tyyyy-MM-dd HH:mm:ss");
System.out.println("\tyyyy/MM/dd HH:mm:ss");
System.out.println("\tyyyy.MM.dd HH:mm:ss");
System.out.println("\tyyyy年MM月dd日 HH时mm分ss秒");
System.out.println("\tyyyy-MM-dd");
System.out.println("\tyyyy/MM/dd");
System.out.println("\tyyyy.MM.dd");
System.out.println("\tHH:mm:ss");
System.out.println("\tHH时mm分ss秒");
System.out.println("\tyyyy-MM-dd HH:mm");
System.out.println("\tyyyy-MM-dd HH:mm:ss.SSS");
System.out.println("\tyyyyMMddHHmmss");
System.out.println("\tyyyyMMddHHmmssSSS");
System.out.println("\tyyyyMMdd");
System.out.println();

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

字符串工具 - StrUtil

1
import static cn.hutool.core.util.StrUtil.*;

与空判断相关的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static boolean isBlank(CharSequence str)
public static boolean isBlankIfStr(Object obj)
public static boolean isNotBlank(CharSequence str)
public static boolean hasBlank(CharSequence... strs)
public static boolean isAllBlank(CharSequence... strs)
public static boolean isEmpty(CharSequence str)
public static boolean isEmptyIfStr(Object obj)
public static boolean isNotEmpty(CharSequence str)
public static String nullToEmpty(CharSequence str)
public static String nullToDefault(CharSequence str, String defaultStr)
public static String emptyToDefault(CharSequence str, String defaultStr)
public static String blankToDefault(CharSequence str, String defaultStr)
public static String emptyToNull(CharSequence str)
public static boolean hasEmpty(CharSequence... strs)
public static boolean isAllEmpty(CharSequence... strs)
public static boolean isNullOrUndefined(CharSequence str)
public static boolean isEmptyOrUndefined(CharSequence str)
public static boolean isBlankOrUndefined(CharSequence str)
public static String cleanBlank(CharSequence str)

头尾处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String trim(CharSequence str)
public static void trim(String[] strs)
public static String trimToEmpty(CharSequence str)
public static String trimToNull(CharSequence str)
public static String trimStart(CharSequence str)
public static String trimEnd(CharSequence str)
public static String trim(CharSequence str, int mode)
public static String strip(CharSequence str, CharSequence prefixOrSuffix)
public static String strip(CharSequence str, CharSequence prefix, CharSequence suffix)
public static String stripIgnoreCase(CharSequence str, CharSequence prefixOrSuffix)
public static String stripIgnoreCase(CharSequence str, CharSequence prefix, CharSequence suffix)
public static String addPrefixIfNot(CharSequence str, CharSequence prefix)
public static String addSuffixIfNot(CharSequence str, CharSequence suffix)
public static boolean isSurround(CharSequence str, CharSequence prefix, CharSequence suffix)
public static boolean isSurround(CharSequence str, char prefix, char suffix)

包含与否

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static boolean startWith(CharSequence str, char c)
public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase)
public static boolean startWith(CharSequence str, CharSequence prefix)
public static boolean startWithIgnoreCase(CharSequence str, CharSequence prefix)
public static boolean startWithAny(CharSequence str, CharSequence... prefixes)
public static boolean endWith(CharSequence str, char c)
public static boolean endWith(CharSequence str, CharSequence suffix, boolean isIgnoreCase)
public static boolean endWith(CharSequence str, CharSequence suffix)
public static boolean endWithIgnoreCase(CharSequence str, CharSequence suffix)
public static boolean endWithAny(CharSequence str, CharSequence... suffixes)
public static boolean contains(CharSequence str, char searchChar)
public static boolean containsAny(CharSequence str, CharSequence... testStrs)
public static boolean containsAny(CharSequence str, char... testChars)
public static boolean containsBlank(CharSequence str)
public static String getContainsStr(CharSequence str, CharSequence... testStrs)
public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr)
public static boolean containsAnyIgnoreCase(CharSequence str, CharSequence... testStrs)
public static String getContainsStrIgnoreCase(CharSequence str, CharSequence... testStrs)

setter gettter 处理

1
2
3
public static String getGeneralField(CharSequence getOrSetMethodName)
public static String genSetter(CharSequence fieldName)
public static String genGetter(CharSequence fieldName)

删除

1
2
3
4
5
6
7
8
9
10
public static String removeAll(CharSequence str, CharSequence strToRemove)
public static String removeAll(CharSequence str, char... chars)
public static String removeAllLineBreaks(CharSequence str)
public static String removePreAndLowerFirst(CharSequence str, int preLength)
public static String removePreAndLowerFirst(CharSequence str, CharSequence prefix)
public static String removePrefix(CharSequence str, CharSequence prefix)
public static String removePrefixIgnoreCase(CharSequence str, CharSequence prefix)
public static String removeSuffix(CharSequence str, CharSequence suffix)
public static String removeSufAndLowerFirst(CharSequence str, CharSequence suffix)
public static String removeSuffixIgnoreCase(CharSequence str, CharSequence suffix)

大小写

1
2
3
4
5
public static String upperFirstAndAddPre(CharSequence str, String preString)
public static String upperFirst(CharSequence str)
public static String lowerFirst(CharSequence str)
public static boolean isUpperCase(CharSequence str)
public static boolean isLowerCase(CharSequence str)

分割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static String[] splitToArray(CharSequence str, char separator)
public static long[] splitToLong(CharSequence str, char separator)
public static long[] splitToLong(CharSequence str, CharSequence separator)
public static int[] splitToInt(CharSequence str, char separator)
public static int[] splitToInt(CharSequence str, CharSequence separator)
public static List<String> split(CharSequence str, char separator)
public static String[] splitToArray(CharSequence str, char separator, int limit)
public static List<String> split(CharSequence str, char separator, int limit)
public static List<String> splitTrim(CharSequence str, char separator)
public static List<String> splitTrim(CharSequence str, CharSequence separator)
public static List<String> splitTrim(CharSequence str, char separator, int limit)
public static List<String> splitTrim(CharSequence str, CharSequence separator, int limit)
public static List<String> split(CharSequence str, char separator, boolean isTrim, boolean ignoreEmpty)
public static List<String> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty)
public static List<String> split(CharSequence str, CharSequence separator, int limit, boolean isTrim, boolean ignoreEmpty)
public static String[] split(CharSequence str, CharSequence separator)
public static String[] split(CharSequence str, int len)
public static String[] cut(CharSequence str, int partLength)

截取

1
2
3
4
5
6
7
8
9
10
11
12
13
public static String sub(CharSequence str, int fromIndex, int toIndex)
public static String subPreGbk(CharSequence str, int len, CharSequence suffix)
public static String maxLength(CharSequence string, int length)
public static String subPre(CharSequence string, int toIndex)
public static String subSuf(CharSequence string, int fromIndex)
public static String subSufByLength(CharSequence string, int length)
public static String subWithLength(String input, int fromIndex, int length)
public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator)
public static String subBefore(CharSequence string, char separator, boolean isLastSeparator)
public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator)
public static String subAfter(CharSequence string, char separator, boolean isLastSeparator)
public static String subBetween(CharSequence str, CharSequence before, CharSequence after)
public static String subBetween(CharSequence str, CharSequence beforeAndAfter)

创建字符串

1
2
3
public static String repeat(char c, int count)
public static String repeat(CharSequence str, int count)
public static String repeatAndJoin(CharSequence str, int count, CharSequence conjunction)

是否相等

1
2
3
4
5
6
public static boolean equals(CharSequence str1, CharSequence str2)
public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2)
public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase)
public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase)
public static boolean isAllCharMatch(CharSequence value, Matcher<Character> matcher)
public static boolean equalsCharAt(CharSequence str, int position, char c)

格式化

1
2
3
public static String format(CharSequence template, Object... params)
public static String indexedFormat(CharSequence pattern, Object... arguments)
public static String format(CharSequence template, Map<?, ?> map)

获取字节

1
2
3
4
public static byte[] utf8Bytes(CharSequence str)
public static byte[] bytes(CharSequence str)
public static byte[] bytes(CharSequence str, String charset)
public static byte[] bytes(CharSequence str, Charset charset)

转换为字符串

1
2
3
4
5
6
7
8
9
10
11
12
public static String utf8Str(Object obj)
public static String str(Object obj, String charsetName)
public static String str(Object obj, Charset charset)
public static String str(byte[] bytes, String charset)
public static String str(byte[] data, Charset charset)
public static String str(Byte[] bytes, String charset)
public static String str(Byte[] data, Charset charset)
public static String str(ByteBuffer data, String charset)
public static String str(ByteBuffer data, Charset charset)
public static String str(CharSequence cs)
public static String toString(Object obj)
public static String join(CharSequence conjunction, Object... objs)

格式转换

1
2
3
public static String toUnderlineCase(CharSequence str)
public static String toSymbolCase(CharSequence str, char symbol)
public static String toCamelCase(CharSequence name)

包裹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String wrap(CharSequence str, CharSequence prefixAndSuffix)
public static String wrap(CharSequence str, CharSequence prefix, CharSequence suffix)
public static String[] wrapAll(CharSequence prefixAndSuffix, CharSequence... strs)
public static String[] wrapAll(CharSequence prefix, CharSequence suffix, CharSequence... strs)
public static String wrapIfMissing(CharSequence str, CharSequence prefix, CharSequence suffix)
public static String[] wrapAllIfMissing(CharSequence prefixAndSuffix, CharSequence... strs)
public static String[] wrapAllIfMissing(CharSequence prefix, CharSequence suffix, CharSequence... strs)

public static String unWrap(CharSequence str, String prefix, String suffix)
public static String unWrap(CharSequence str, char prefix, char suffix)
public static String unWrap(CharSequence str, char prefixAndSuffix)
public static boolean isWrap(CharSequence str, String prefix, String suffix)
public static boolean isWrap(CharSequence str, String wrapper)
public static boolean isWrap(CharSequence str, char wrapper)
public static boolean isWrap(CharSequence str, char prefixChar, char suffixChar)

填充

1
2
3
4
5
6
public static String padPre(CharSequence str, int minLength, char padChar)
public static String padEnd(CharSequence str, int minLength, char padChar)
public static StringBuilder builder()
public static String fillBefore(String str, char filledChar, int len)
public static String fillAfter(String str, char filledChar, int len)
public static String fill(String str, char filledChar, int len, boolean isPre)

获取其他对象

1
2
3
4
5
6
7
public static StrBuilder strBuilder()
public static StringBuilder builder(int capacity)
public static StrBuilder strBuilder(int capacity)
public static StringBuilder builder(CharSequence... strs)
public static StrBuilder strBuilder(CharSequence... strs)
public static StringReader getReader(CharSequence str)
public static StringWriter getWriter()

出现次数

1
2
public static int count(CharSequence content, CharSequence strForSearch)
public static int count(CharSequence content, char charForSearch)

摘要和隐藏

1
2
public static String brief(CharSequence str, int maxLength)
public static String hide(CharSequence str, int startInclude, int endExclude)

比较

1
2
3
public static int compare(final CharSequence str1, final CharSequence str2, final boolean nullIsLess)
public static int compareIgnoreCase(CharSequence str1, CharSequence str2, boolean nullIsLess)
public static int compareVersion(CharSequence version1, CharSequence version2)

获取索引位置

1
2
3
4
5
6
7
8
9
10
public static int indexOf(final CharSequence str, char searchChar)
public static int indexOf(final CharSequence str, char searchChar, int start)
public static int indexOf(final CharSequence str, char searchChar, int start, int end)
public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex)
public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase)
public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex)
public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase)
public static int ordinalIndexOf(String str, String searchStr, int ordinal)

追加

1
2
3
4
5
6
public static String appendIfMissing(final CharSequence str, final CharSequence suffix, final CharSequence... suffixes)
public static String appendIfMissingIgnoreCase(final CharSequence str, final CharSequence suffix, final CharSequence... suffixes)
public static String appendIfMissing(final CharSequence str, final CharSequence suffix, final boolean ignoreCase, final CharSequence... suffixes)
public static String prependIfMissing(final CharSequence str, final CharSequence prefix, final CharSequence... prefixes)
public static String prependIfMissingIgnoreCase(final CharSequence str, final CharSequence prefix, final CharSequence... prefixes)
public static String prependIfMissing(final CharSequence str, final CharSequence prefix, final boolean ignoreCase, final CharSequence... prefixes)

替换

1
2
3
4
5
6
7
8
9
public static String replaceIgnoreCase(CharSequence str, CharSequence searchStr, CharSequence replacement)
public static String replace(CharSequence str, CharSequence searchStr, CharSequence replacement)
public static String replace(CharSequence str, CharSequence searchStr, CharSequence replacement, boolean ignoreCase)
public static String replace(CharSequence str, int fromIndex, CharSequence searchStr, CharSequence replacement, boolean ignoreCase)
public static String replace(CharSequence str, int startInclude, int endExclude, char replacedChar)
public static String replace(CharSequence str, Pattern pattern, Func1<java.util.regex.Matcher, String> replaceFun)
public static String replace(CharSequence str, String regex, Func1<java.util.regex.Matcher, String> replaceFun)
public static String replaceChars(CharSequence str, String chars, CharSequence replacedStr)
public static String replaceChars(CharSequence str, char[] chars, CharSequence replacedStr)

相似度

1
2
public static double similar(String str1, String str2)
public static String similar(String str1, String str2, int scale)

其他

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//总长度
public static int totalLength(CharSequence... strs)

//移动
public static String move(CharSequence str, int startInclude, int endExclude, int moveLength)

//uuid
public static String uuid()

//连接
public static String concat(boolean isNullToEmpty, CharSequence... strs)

//反转
public static String reverse(String str)

数字工具

TestNumber.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestNumber {

@Test
@Comment("精确计算")
public void test1(){
double result1 = (1.2 - 0.4);
p3("浮点数计算 1.2 - 0.4 无法得到精确结果",result1);
double result2 = NumberUtil.sub(1.2, 0.4);
p3("浮点数计算 NumberUtil.sub(1.2,0.4) 就能得到精确结果",result2);
}
@Test
@Comment("四舍五入")
public void test2(){
double a = 100.123;
double b = 100.125;

double result1= NumberUtil.round(a, 2).doubleValue();
double result2= NumberUtil.round(b, 2).doubleValue();

p1("浮点数", a, "四舍五入之后", result1);
p1("浮点数", b, "四舍五入之后", result2);

}
@Test
@Comment("数字格式化")
public void test3(){

// 0 -> 取一位整数
// 0.00 -> 取一位整数和两位小数
// 00.000 -> 取两位整数和三位小数
// # -> 取所有整数部分
// #.##% -> 以百分比方式计数,并取两位小数
// #.#####E0 -> 显示为科学计数法,并取五位小数
// ,### -> 每三位以逗号进行分隔,例如:299,792,458
// 光速大小为每秒,###米 -> 将格式嵌入文本

p3("对π进行格式化,π的值是",Math.PI);
double pi= Math.PI;
String format = null;
String str = null;
format= "0";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "0.00";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "00.000";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "#";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "#.##";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "#.##%";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= "#.####E0";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

format= ",###";
str = NumberUtil.decimalFormat(format,pi*10000);
p2("格式",format,"x1000 再格式化后得到", str);

format= ",####";
str = NumberUtil.decimalFormat(format,pi*10000);
p2("格式",format,"x1000 再格式化后得到", str);

format= "π的大小是#.##########,请课后记忆";
str = NumberUtil.decimalFormat(format,pi);
p2("格式",format,"格式化后得到", str);

}
@Test
@Comment("数字判断")
public void test4(){
String s1 = "3.1415926";
int n = 11;
p2("字符串",s1, "是否数字",NumberUtil.isNumber(s1));
p2("字符串",s1, "是否整数(这个有问题)",NumberUtil.isInteger(s1));
p2("字符串",s1, "是否浮点数",NumberUtil.isDouble(s1));
p2("整数",n, "是否质数",NumberUtil.isPrimes(n));
}
@Test
@Comment("随机数")
public void test5(){
int random[]=NumberUtil.generateRandomNumber(1,1000,10);

p3("最小是1,最大是1000,总长度是10的不重复随机数组",Convert.toStr(random));
}
@Test
@Comment("整数列表")
public void test6(){
int numbers[] = NumberUtil.range(0, 100, 9);
p3("最小是0,最大是100,步长是9的数组",Convert.toStr(numbers));
}
@Test
@Comment("其他相关")
public void test7(){

p3("计算3的阶乘", NumberUtil.factorial(3));
p3("计算9的平方根", NumberUtil.sqrt(9));
p3("计算9和6的最大公约数", NumberUtil.divisor(9,6));
p3("计算9和6的最小公倍数", NumberUtil.multiple(9,6));
p3("获得数字9对应的二进制字符串", NumberUtil.getBinaryStr(9));
p3("获取123456789对应金额", NumberUtil.decimalFormatMoney(123456789));
}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

数组工具

TestArray.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Map;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestArray {

@Test
@Comment("为空判断")
public void test1() {
int[] a = null;
int[] b = new int[5];
int[] c = new int[]{10, 11, 12};

p1("数组", Convert.toStr(a), "是否为空", ArrayUtil.isEmpty(a));
p1("数组", Convert.toStr(b), "是否为空", ArrayUtil.isEmpty(b));
p1("数组", Convert.toStr(c), "是否为空", ArrayUtil.isEmpty(c));

}

@Test
@Comment("调整数组大小")
public void test2() {
Integer[] a = new Integer[]{10, 11, 12};
Integer[] b = ArrayUtil.resize(a, 5);

p3("调整大小前的数组", Convert.toStr(a));
p3("调整大小后的数组", Convert.toStr(b));

}

@Test
@Comment("合并数组")
public void test3() {
Integer[] a = {1, 2, 3};
Integer[] b = {10, 11, 12};
Integer[] c = ArrayUtil.addAll(a, b);

p2("合并前的两个数组 ", Convert.toStr(a) + " , " + Convert.toStr(b), "合并后的数组是", Convert.toStr(c));
}

@Test
@Comment("克隆")
public void test4() {
Integer[] a = {1, 2, 3};
Integer b[] = ArrayUtil.clone(a);

p2("原数组", Convert.toStr(a), "克隆的数组", Convert.toStr(b));

}

@Test
@Comment("生成有序数组")
public void test5() {
p3("生成开始是0,结束是100,步长是9的有序数组", Convert.toStr(ArrayUtil.range(0, 100, 9)));
}

@Test
@Comment("过滤")
public void test6() {
Integer[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Integer[] b = ArrayUtil.filter(a, new Filter<Integer>() {

@Override
public boolean accept(Integer t) {
if (0 == t % 3)
return true;
return false;
}

});

p2("原数组", Convert.toStr(a), "3的倍数过滤之后", Convert.toStr(b));

}

@Test
@Comment("转换为map")
public void test7() {
Integer a[] = {1, 2, 3};
String c[] = {"a", "b", "c"};
Map<Integer, String> m = ArrayUtil.zip(a, c);

p2("两个数组", Convert.toStr(a) + " , " + Convert.toStr(c), "转换为 Map ", m);

}

@Test
@Comment("是否包含某元素")
public void test8() {
Integer a[] = {1, 2, 3};

p1("数组", Convert.toStr(a), "是否包含元素3", ArrayUtil.contains(a, 3));

}

@Test
@Comment("装箱拆箱")
public void test9() {
int a[] = {1, 2, 3};
Integer b[] = ArrayUtil.wrap(a);
int c[] = ArrayUtil.unWrap(b);

p3("数组基本类型的装箱拆箱", "ArrayUtil.wrap | ArrayUtil.unWrap");
}

@Test
@Comment("转换为字符串")
public void testa() {
int a[] = {1, 2, 3};

p3("数组转换为默认字符串", ArrayUtil.toString(a));
p3("数组转换为自定义分隔符的字符串", ArrayUtil.join(a, "-"));

}

@Test
@Comment("拆分")
public void testb() {

byte[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};

byte[][] b = ArrayUtil.split(a, 2);

p3("数组被拆成2为长度的等份", Convert.toStr(a));

for (byte[] bs : b) {
p3("拆分后的数组:", Convert.toStr(bs));
}

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

随机工具

TestRandom.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestRandom {

@Test
@Comment("各种各样的随机数")
public void test1() {
List<Integer> ls = new ArrayList<>();
ls.add(1);
ls.add(2);
ls.add(3);

p3("随机获取一个整数", RandomUtil.randomInt(1, 1000));
p3("随机获取一个字节数组", Convert.toStr(RandomUtil.randomBytes(3)));

p3("随机获取一个集合里的某个元素", RandomUtil.randomEle(ls));

p3("随机获取一个字符串", RandomUtil.randomString(10));
p3("随机获取一个大写字符串", RandomUtil.randomStringUpper(10));
p3("随机获取一个数字字符串", RandomUtil.randomNumbers(10));
p3("随机获取一个UUID", RandomUtil.randomUUID());
p3("随机获取一个简化的UUID", RandomUtil.simpleUUID());

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

比较器工具

TestComparator.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package cn.how2j.test;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Test;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

public class TestComparator {
@Test
@Comment("属性比较器")
public void test1() {
List<Hero> heros = new ArrayList<>();
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i, RandomUtil.randomInt(100)));
}
System.out.println("未排序的集合:");
System.out.println(CollectionUtil.join(heros, "\r\n"));

Collections.sort(heros, new PropertyComparator<>("hp"));
System.out.println("根据属性 hp 排序之后:");
System.out.println(CollectionUtil.join(heros, "\r\n"));
}

@Test
@Comment("拼音比较器")
public void test2() {
List<String> names = new ArrayList<>();
names.add("令狐冲");
names.add("陈家洛");
names.add("石破天");
names.add("胡一刀");

p3("未排序的集合", CollectionUtil.join(names, " , "));

Collections.sort(names, new PinyinComparator());
p3("根据拼音排序的集合", CollectionUtil.join(names, " , "));
}

class Hero {
String name;
int hp;

public Hero(String name, int hp) {
super();
this.name = name;
this.hp = hp;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getHp() {
return hp;
}

public void setHp(int hp) {
this.hp = hp;
}

@Override
public String toString() {
return "Hero [name=" + name + ", hp=" + hp + "]";
}

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

多线程工具

TestThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutionException;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestThread {
@Test
@Comment("多线程工具")
public void test1() throws InterruptedException, ExecutionException {
p3("所有线程", ArrayUtil.join(ThreadUtil.getThreads(), "\r\n\t\t\t\t"));
p3("获取主线程", ThreadUtil.getMainThread());

p3("不用捕捉异常的sleep", "ThreadUtil.sleep(2000);");
ThreadUtil.sleep(2000);


p3("很方便的通过线程池执行任务", "");
for (int i = 0; i < 10; i++) {
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("\t\t当前线程是:" + Thread.currentThread());
}
};
ThreadUtil.execute(r);

}


}


private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

缓存工具

TestCache.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.file.LFUFileCache;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestCache {
@Test
@Comment("缓存工具")
public void test0() {
p4("hutool的缓存,在处理缓存满了或者到期的时候,有如下几种策略:");

p3("FIFOCache", "first in first out , 先入先出,一旦缓存满了,先放进去的,先被清空");
p3("LFUCache", "least frequently used, 一旦缓存满了,用得最少的,先被清空 (命中低的数据被清空)");
p3("LRUCache", "least recently used, 一旦缓存满了,最久没用的,先被清空 (旧数据被清空)");
p3("TimedCache", "一旦时间到了,被清空 (考虑时效性)");
p3("WeakCache", "一旦内存满了,要垃圾回收了,优先被清空 (内存占用重要性)");
p3("FileCach", "把文件对象作为缓存,减少IO访问频率");

// LFUCache
// LRUCache least recently used
// TimedCache
// WeakCache
// FileCach
}

@Test
@Comment("FIFO 示例")
public void test1() {
p4("初始化缓存大小是 2");
p4("接着向里面挨个放入1,2,3,导致缓存变满");
Cache<String, Integer> cache = CacheUtil.newFIFOCache(2);
cache.put("key1", 1);
cache.put("key2", 2);
cache.put("key3", 3);
p3("遍历缓存中的数据", CollectionUtil.join(cache, ","));
p4("如预料一般,最早放入的最先被清空");
}

@Test
@Comment("LFUCache 示例")
public void test2() {
p4("初始化缓存大小是 2");
p4("接着向里面挨个放入1,2,3,导致缓存变满");
Cache<String, Integer> cache = CacheUtil.newLFUCache(2);
cache.put("key1", 1);
cache.put("key2", 2);
p4("中途故意使用一次 key1");
cache.get("key1");
cache.put("key3", 3);
p3("遍历缓存中的数据", CollectionUtil.join(cache, ","));
p4("如预料一般,使用频率最低的 2 的被清空");
}

@Test
@Comment("LFUCache 示例")
public void test3() {
p4("初始化缓存大小是 2");
p4("接着向里面挨个放入1,2,3,导致缓存变满");
Cache<String, Integer> cache = CacheUtil.newLRUCache(2);
cache.put("key1", 1);
cache.put("key2", 2);
p4("中途故意使用一次 key1");
cache.get("key1");
cache.put("key3", 3);
p3("遍历缓存中的数据", CollectionUtil.join(cache, ","));
p4("如预料一般,最久没有被使用的 2 的被清空");
}

@Test
@Comment("TimedCache 示例")
public void test4() {
p4("初始化缓存大小是 2");
p4("接着向里面挨个放入1,2, 分别放设置存放时间为1秒和5秒");
Cache<String, Integer> cache = CacheUtil.newTimedCache(Integer.MAX_VALUE);
cache.put("key1", 1, 1000);
cache.put("key2", 2, 5000);
p4("休息3秒");
ThreadUtil.sleep(3000);
p3("遍历缓存中的数据", CollectionUtil.join(cache, ","));
p4("如预料一般, 经过3秒后,1被清空了,2还在");
}

@Test
@Comment("WeakCache 示例")
public void test5() {
p4("WeekCache表示当垃圾回收发生的时候,不会阻挡回收器把它回收走。");

p4("请注意看描述:\"不会阻挡\", 就是说,垃圾回收真正要对它下手了,是可以下手的。");
p4("但是垃圾回收发生的时候,不一定会回收所有垃圾和 week引用。");
p4("正因为如此,不易观察到现象,而且不稳定,所以就不做演示了,免得误导");

}

@Test
@Comment("FileCache 示例")
public void test6() {
p4("FileCache 也分 LFU, LRU 等,只是调用方式有所区别,并没有被放到 CacheUtil里,找了好一会儿才找到。。。,");
//参数1:容量,能容纳的byte数
//参数2:最大文件大小,byte数,决定能缓存至少多少文件,大于这个值不被缓存直接读取
//参数3:超时。毫秒

long capacity = 1024 * 1024 * 500; //最多500m, 太大了,内存吃不消,缓存就没法实施了
long maxFileSize = 1024 * 1024 * 10; //最大10m, 文件小于这个就缓存,太大了也不缓存
long timeout = 1000 * 60 * 60 * 24; //缓存一天,超过这个就自动从缓存里移除了

LFUFileCache cache = new LFUFileCache(1024 * 1024 * 500, 500, 2000);
//使用办法:
//byte[] bytes = cache.getFileBytes("e:/project/hutool/img/logo.png");

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p4(Object value) {
p(null, value, "", "", "format4");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
if ("format4".equals(format)) {
System.out.printf("\t%s%n%n", value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

定时器工具

HutoolCronTask

1
2
3
4
5
6
7
8
9
10
11
12
package cn.how2j;

import cn.hutool.core.date.DateUtil;

public class HutoolCronTask implements Runnable{

@Override
public void run() {
System.out.println(DateUtil.now() + " this is HutoolCronTask");
}

}

cron.settings

配置文件,cron.settings, 要放在 /resources/config 目录下。

1
2
[cn.how2j]
HutoolCronTask.run = */2 * * * * ?

TestCron

1
2
3
4
5
6
7
8
9
10
11
package cn.how2j;

import cn.hutool.cron.CronUtil;

public class TestCron {

public static void main(String[] args) {
CronUtil.setMatchSecond(true);
CronUtil.start();
}
}

用代码添加任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package cn.how2j;

import cn.hutool.core.date.DateUtil;
import cn.hutool.cron.CronUtil;

public class TestCron {

public static void main(String[] args) {
CronUtil.setMatchSecond(true);
CronUtil.start();

CronUtil.schedule("*/2 * * * * ?", new Runnable() {

@Override
public void run() {
System.out.println(DateUtil.now() + " 执行新任务");

}
});
}
}

类和对象

反射工具

TestReflection.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package cn.how2j.test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Test;

import java.lang.annotation.*;
import java.lang.reflect.Method;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

public class TestReflection {

class Hero {
String name;
int hp;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getHp() {
return hp;
}

public void setHp(int hp) {
this.hp = hp;
}
}

@Test
@Comment("设置属性")
public void test1() {
Hero h = new Hero();
ReflectUtil.setFieldValue(h, "name", "盖伦");
p3("对象通过反射设置name属性后的值", h.getName());
}

@Test
@Comment("调用方法")
public void test2() {
Hero h = new Hero();
ReflectUtil.invoke(h, "setName", "盖伦");
p3("对象通过反射设置调用setName属性后的值", h.getName());
}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

类工具

获取方法

1
2
3
4
5
6
7
8
9
10
public static Set<String> getPublicMethodNames(Class<?> clazz) 
public static Method[] getPublicMethods(Class<?> clazz)
public static List<Method> getPublicMethods(Class<?> clazz, Filter<Method> filter)
public static List<Method> getPublicMethods(Class<?> clazz, Method... excludeMethods)
public static List<Method> getPublicMethods(Class<?> clazz, String... excludeMethodNames)
public static Method getPublicMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
public static Set<String> getDeclaredMethodNames(Class<?> clazz)
public static Method[] getDeclaredMethods(Class<?> clazz)
public static Method getDeclaredMethodOfObj(Object obj, String methodName, Object... args)
public static Method getDeclaredMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes)

获取字段

1
2
public static Field getDeclaredField(Class<?> clazz, String fieldName) 
public static Field[] getDeclaredFields(Class<?> clazz)

调用方法

1
2
3
4
public static <T> T invoke(String classNameDotMethodName, Object[] args) 
public static <T> T invoke(String classNameWithMethodName, boolean isSingleton, Object... args)
public static <T> T invoke(String className, String methodName, Object[] args)
public static <T> T invoke(String className, String methodName, boolean isSingleton, Object[] args)

系统工具

粘贴板工具

TestClipboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.swing.ClipboardUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestClipboard {

@Test
@Comment("粘贴版")
public void test1() {
String s1 = "how2j.cn- java教程";
ClipboardUtil.setStr(s1);

String s2 = ClipboardUtil.getStr();

p3("把如下数据通过ClipboardUtil 保存到粘贴板里", s1);

p3("通过ClipboardUtil 从粘贴板里取数据", s2);

//注意此文件是否真的存在
String imagePath = "d:/temp.png";
// Image img =ImageUtil.read(imagePath);
// ClipboardUtil.setImage(img);
// img = ClipboardUtil.getImage();
p3("向粘贴板复制图片的用法:", "ClipboardUtil.setImage(img)");
p3("从粘贴板获取图片的用法:", "ClipboardUtil.getImage()");
}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

运行时工具

TestRuntime

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package cn.how2j.test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Test;

import java.lang.annotation.*;
import java.lang.reflect.Method;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

public class TestRuntime {

@Test
@Comment("RuntimeUtil使用举例")
public void test1() {
String s = RuntimeUtil.execForStr("netstat -n");

System.out.println(s);
}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

系统属性工具

TestSystem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cn.how2j.test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import org.junit.Test;

import java.lang.annotation.*;
import java.lang.reflect.Method;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

public class TestSystem {

@Test
@Comment("系统属性工具")
public void test1() {
p5("java虚拟机规范", StrUtil.trim(SystemUtil.getJvmSpecInfo().toString()));
p5("当前虚拟机信息", StrUtil.trim(SystemUtil.getJvmInfo().toString()));
p5("java规范", StrUtil.trim(SystemUtil.getJavaSpecInfo().toString()));
p5("当前java信息", StrUtil.trim(SystemUtil.getJavaInfo().toString()));
p5("java运行时信息", StrUtil.trim(SystemUtil.getJavaRuntimeInfo().toString()));
p5("操作系统信息", StrUtil.trim(SystemUtil.getOsInfo().toString()));
p5("用户信息", StrUtil.trim(SystemUtil.getUserInfo().toString()));
p5("主机信息", StrUtil.trim(SystemUtil.getHostInfo().toString()));
p5("内存信息", StrUtil.trim(SystemUtil.getRuntimeInfo().toString()));
}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p5(String type1, Object value1) {
p(type1, value1, "", "", "format5");
}

private void p4(Object value) {
p(null, value, "", "", "format4");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
if ("format4".equals(format)) {
System.out.printf("\t%s%n%n", value1);
}
if ("format5".equals(format)) {
System.out.printf("---------%s-------:%n%s %n%n", type1, value1);
}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

文件相关

文件IO工具

  • Hutool 里的文件IO工具有好几个
  • IOUtil :操作流的
  • FileUtil :操作文件的
  • FileTypeUtil: 被包含在FileUtil里了
  • FileReader,FileWriter:这两个基本上都在FileUtil里用了
  • WatchMonitor: 用来监控文件变化, 这个比较有意思,可以看看自己c盘,平时文件都有什么变化。
  • ClassPathResource 是class 路径下资源的获取

IOUtil

把输入流的数据复制到输出流中

1
2
3
4
5
6
7
8
9
10
11
long copy(InputStream in, OutputStream out)
```

> 读取输入流的内容为字符串
```java
String read(InputStream in, String charsetName)
```

> 把数据写出到输出流中
```java
void writeUtf8(OutputStream out, boolean isCloseOut, Object... contents)

FileUtil

是否是windows系统 (通过分隔符进行判断)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
boolean isWindows
```

> 追加数据
```java
File appendString(String content, File file, String charset)
```

> 遍历当前目录及其子目录
```java
List<File> loopFiles(String path)
```

> 目录及其子目录所有文件的大小总和
```java
long size(File file)
```

> 创建文件,会自动创建父文件夹。 方法名故意用linux下的命令名
```java
File touch(String fullFilePath)
```

> 删除文件或者目录(这个很危险,会自动删除当前目录以及子目录,慎用)
```java
boolean del(String fullFileOrDirPath)
```

> 同上
```java
static boolean clean(String dirPath)
```

> 复制文件或者目录
```java
File copyFile(String src, String dest, StandardCopyOption... options)
```

> 判断俩文件内容是否一样
```java
boolean contentEquals(File file1, File file2)
```

> 获取后缀名,不带.
```java
String extName(String fileName)
```

> 根据文件头部信息获取文件类型
```java
String getType(File file)
```

> 读取内容为字符串
```java
readString(String path, String charsetName)
```

> 读取内容为集合
```java
List<String> readLines(String path, String charset)
```

> 把字符串写入到文件
```java
File writeString(String content, String path, String charset)
```

> 把集合写入到文件
```java
File writeLines(Collection<T> list, File file, String charset)
```

> 转换文件编码,第一个参数必须和文件本身编码保持一致,否则就会出错。比如一个文件是GBK的,但是在UTF默认编码的环境下看到都是乱码,就可以通过这个转换一下
```java
File convertCharset(File file, Charset srcCharset, Charset destCharset)
```

> 指定换行符,有些文件从Linux搞来的,在window下换行会混乱,可以用这个进行转换
```java
convertLineSeparator(File file, Charset charset, LineSeparator lineSeparator)
```

> 获取CRC32校验码
```java
long checksumCRC32(File file)
```

> 获取Web项目下的web root路径
```java
File getWebRoot()
```

> 根据文件后缀名 (不一定是真实格式),获取其mimetype
```java
String getMimeType(String filePath)

WatchMonitor

这是监控 F:/game 目录下所有文件的增删改。
站长启动了 “They Are Billions”, 就观察到了这么一些文件变化,哈哈~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package cn.how2j;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.WatchEvent;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.core.io.watch.Watcher;
import cn.hutool.core.lang.Console;

public class TestWatchMonitor {

public static void main(String[] args) {
File file = FileUtil.file("F:/game");
//这里只监听文件或目录的修改事件
WatchMonitor watchMonitor = WatchMonitor.create(file, WatchMonitor.EVENTS_ALL);
watchMonitor.setWatcher(new Watcher() {
@Override
public void onCreate(WatchEvent<?> event, Path currentPath) {
Object obj = event.context();
Console.log("创建:{}-> {}", currentPath, obj);
}

@Override
public void onModify(WatchEvent<?> event, Path currentPath) {
Object obj = event.context();
Console.log("修改:{}-> {}", currentPath, obj);
}

@Override
public void onDelete(WatchEvent<?> event, Path currentPath) {
Object obj = event.context();
Console.log("删除:{}-> {}", currentPath, obj);
}

@Override
public void onOverflow(WatchEvent<?> event, Path currentPath) {
Object obj = event.context();
Console.log("Overflow:{}-> {}", currentPath, obj);
}
});

//设置监听目录的最大深入,目录层级大于制定层级的变更将不被监听,默认只监听当前层级目录
watchMonitor.setMaxDepth(Integer.MAX_VALUE);
//启动监听
watchMonitor.start();
}
}

ClassPathResource

ClassPathResource 是专门用来读取classpath 里的数据的,很方便。
如代码所所示,读取 hutoool jar 包里的:META-INF/MANIFEST.MF 文件并打印出来了。。。

如果不是用ClassPathResource ,要做还略麻烦的呢

TestFile.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package cn.how2j.test;

import org.junit.Test;

import cn.hutool.core.io.resource.ClassPathResource;

public class TestFile {

@Test
public void test1() {
ClassPathResource resource = new ClassPathResource("META-INF/MANIFEST.MF");
System.out.println(resource.readUtf8Str());
}
}

图片工具

  • 缩放 scale
  • 切割 cut
  • 切片 slice
  • 类型转换 convert
  • 灰度 gray
  • 添加文字水印 pressText
  • 添加图片水印 pressImage
  • 旋转 rotate
  • 水平翻转 flip
  • 图片变成BASE-64字符串 toBase64
  • 创建字体 createFont
  • 根据文字创建图片 createImage
  • 读取图片 read
  • 随机颜色 randomColor

CSV工具

TestCVS.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cn.how2j.test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.csv.*;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Test;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.List;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

public class TestCVS {

@Test
@Comment("读写CVS")
public void test1() {

//写数据
CsvWriter writer = CsvUtil.getWriter("test.csv", CharsetUtil.CHARSET_UTF_8);
writer.write(
new String[]{"a1", "b1", "c1"},
new String[]{"a2", "b2", "c2"},
new String[]{"a3", "b3", "c3"}
);
//读数据

CsvReader reader = CsvUtil.getReader();
//从文件中读取CSV数据
CsvData data = reader.read(FileUtil.file("test.csv"));
List<CsvRow> rows = data.getRows();
//遍历行
for (CsvRow csvRow : rows) {
//getRawList返回一个List列表,列表的每一项为CSV中的一个单元格(既逗号分隔部分)
System.out.println(csvRow.getRawList());
}

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

图形验证码工具

TestCaptcha.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.io.OutputStream;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestCaptcha {

@Test
@Comment("创建 线段干扰的验证码")
public void test1() {
int width = 200;
int height = 100;
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
p3("当前的验证码是", captcha.getCode());
String path = "d:/captcha1.png";
captcha.write(path);
}

@Test
@Comment("创建 圆圈干扰的验证码")
public void test2() {
int width = 200;
int height = 100;
int codeCount = 5;
int circleCount = 40;
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height, codeCount, circleCount);
p3("当前的验证码是", captcha.getCode());
String path = "d:/captcha2.png";
captcha.write(path);
}

@Test
@Comment("创建 扭曲线干扰的验证码")
public void test3() {
int width = 200;
int height = 100;
int codeCount = 5;
int thickness = 2;
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height, codeCount, thickness);
p3("当前的验证码是", captcha.getCode());
String path = "d:/captcha3.png";
captcha.write(path);
}

@Test
@Comment("web 页面输出")
public void test4() {
//junit 毕竟不是servlet 容器,拿不到 response对象, 这里是伪代码
int width = 200;
int height = 100;
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
OutputStream out = null;
// out = HttpServletResponse.getOutputStream();
// captcha.write(out);
IoUtil.close(out);
}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t被转换为----->%n\t%s:\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

第三方相关

邮件工具

TestMail.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Before;
import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;

public class TestMail {
private MailAccount account;

@Before
public void prepareMailAccount() {
account = new MailAccount();
account.setHost("smtp.163.com");
account.setPort(25);
account.setAuth(true);
account.setFrom("test@163.com"); //假邮箱,请自己申请真实邮箱
account.setUser("test@163.com"); //假邮箱,请自己申请真实邮箱
account.setPass("testpassword"); //假密码,请自己申请真实邮箱
}

@Test
@Comment("发送普通文本")
public void test1(){
//因为账号密码不对,所以不能正确发送
//MailUtil.send(account,"test@163.com", "hutool 测试邮件" + DateUtil.now(), "测试内容", false);
}
@Test
@Comment("发送html邮件")
public void test2(){
//因为账号密码不对,所以不能正确发送
//MailUtil.send(account,"test@163.com", "hutool 测试邮件" + DateUtil.now(), "<p>测试内容</p>", true);
}
@Test
@Comment("发送带附件的邮件")
public void test3(){

//因为账号密码不对,所以不能正确发送
MailUtil.send(account,"test@163.com", "hutool 测试邮件" + DateUtil.now(), "<p>测试内容</p>", true, FileUtil.file("d:/test.txt"));
}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

pom.xml
从现在开始,都是需要第三方包 才能使用的 hutool 功能了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.how2j</groupId>
<artifactId>hutool</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hutool</name>
<description>hutool</description>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
</dependencies>
</project>

qq邮箱

关于qq邮箱如果要使用,密码要使用授权码。 授权码的获取手段:
https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256

二维码工具

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.how2j</groupId>
<artifactId>hutool</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hutool</name>
<description>hutool</description>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>
</project>

TestQR.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;

public class TestQR {

@Test
@Comment("生成二维码图片和解析图片")
public void test1(){
String string = "http://how2j.cn";
String path = "d:/qrcode.jpg";
QrCodeUtil.generate(string, 300, 300, FileUtil.file(path));

p1("字符串",string,"二维码图片",path);

string = QrCodeUtil.decode(FileUtil.file(path));
p1("二维码图片",path,"二维码图片",string);

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

FTP工具

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.how2j</groupId>
<artifactId>hutool</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hutool</name>
<description>hutool</description>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
</dependencies>
</project>

TestFtp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ftp.Ftp;

public class TestFTP {

@Test
@Comment("上传下载")
public void test1(){

String localFile4Upload = "d:/test.jpg";
String localFile4Download = "d:/test2.jpg";
String remoteFolder = "/";
String remoteFile = "test.jpg";
String ftpServer = "28.212.18.5"; //这是无效的ip地址,请使用自己有效的ftp服务器ip地址
String name = "ftpuser";
String password = "password123";

Ftp ftp = new Ftp(ftpServer,21,name,password);
boolean success= ftp.upload(remoteFolder,remoteFile, FileUtil.file(localFile4Upload));
p3("上传是否成功",success);

ftp.download(remoteFolder, remoteFile, FileUtil.file(localFile4Download));

p3("用于上传的文件大小", FileUtil.file(localFile4Upload).length());
p3("下载下来之后的文件大小", FileUtil.file(localFile4Download).length());

try {
ftp.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

其他

网络工具

TestNet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NetUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestNet {

@Test
@Comment("ipv4 和 long 互换")
public void test1(){
String ip = "220.181.57.216";
long value = 0L;

value = NetUtil.ipv4ToLong(ip);
ip = NetUtil.longToIpv4(value);
p2("ip地址",ip, "对应的long", value);
p2("long值 ",value, "对应的ip", ip);

}

@Test
@Comment("判断端口和地址")
public void test2(){
int port1 =80;
int port2 =68000;
String ip1 = "220.181.57.216";
String ip2 = "192.168.0.8";
p2("端口号",port1, "是否已经被占用",!NetUtil.isUsableLocalPort(port1));
p2("端口号",port2, "是否一个有效的端口号",NetUtil.isValidPort(port2));
p2("ip地址",ip1, "是否是个内网地址",NetUtil.isInnerIP(ip1));
p2("ip地址",ip2, "是否是个内网地址",NetUtil.isInnerIP(ip2));
}

@Test
@Comment("其他相关操作")
public void test3(){

String ip = "220.181.57.216";
String host = "baidu.com";

p2("原ip",ip,"隐藏最后一位",NetUtil.hideIpPart(ip));
p2("域名",host,"对应的ip地址",NetUtil.getIpByHost(host));
p3("本机ip地址",NetUtil.localIpv4s());
p3("本机mac地址",NetUtil.getLocalMacAddress());

}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

压缩工具

TestZip.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;

public class TestZip {

@Test
@Comment("压缩字符串")
public void test1(){
String str = "hello!!!!!!!!!!!!!!!";
byte[] bs= ZipUtil.zlib(str, "utf-8", 4);
String str2 = ZipUtil.unZlib(bs, "utf-8");

p3("源字符串",str);
p3("长度是",str.length());
p3("zlib压缩后,长度是",bs.length);
p3("unzip后得到",str2);

}
@Test
@Comment("压缩文件")
public void test2(){
System.out.println("\t因为是压缩文件,不好演示,主要就是使用 zip和unzip方法,很好用,都挨个试试就知道了");
}

private String preComment = null;
private void c(String msg) {
System.out.printf("\t备注:%s%n",msg);
}
private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}
private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}
private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m =ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if(null!=annotation) {
String comment= annotation.value();
if(!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n",comment);
preComment = comment;
}

}
}
int padLength = 12;
type1=StrUtil.padEnd(type1,padLength,Convert.toSBC(" ").charAt(0));
type2=StrUtil.padEnd(type2,padLength,Convert.toSBC(" ").charAt(0));
if("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n",type1,value1, type2, value2);
}
if("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n",type1,value1, type2, value2);
}
if("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n",type1,value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if(methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

正则工具

TestRegex.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestRegex {

@Test
@Comment("正则表达式")
public void test1() {
String content = "But just as he who called you is holy, so be holy in all you do; for it is written: “Be holy, because I am holy";

p3("字符串",content);
String regex = "\\w{5}";
p3(regex + " 表:","连续5个字母或者数字");

Object result = ReUtil.get(regex, content, 0);
p2("正则表达式",regex,"get 返回值", result);

result = ReUtil.contains(regex, content);
p2("正则表达式",regex,"contain 返回值", result);

result = ReUtil.count(regex, content);
p2("正则表达式",regex,"count 返回值", result);

result = ReUtil.delAll(regex, content);
p2("正则表达式",regex,"delAll 返回值", result);

result = ReUtil.delFirst(regex, content);
p2("正则表达式",regex,"delFirst 返回值", result);

result = ReUtil.delPre(regex, content);
p2("正则表达式",regex,"delPre 返回值", result);

result = ReUtil.findAll(regex, content,0);
p2("正则表达式",regex,"findAll 返回值", result);

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({ METHOD, TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

校验工具

TestValidator.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestValidator {

@Test
@Comment("校验器")
public void test1() {
String email ="123@qq.com";
boolean valid =Validator.isEmail(email);

p2("邮件地址",email," 是否合法 ",valid);

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({ METHOD, TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}

归纳
Validator 把一些常用的校验工具准备好了,提供给大家直接使用。
用法都很简单,这里站长稍做整理,归纳了一下。

  • 为空判断
    isNull
    isEmpty
  • 字母,数字和下划线
    isGeneral
  • 至少多长的
    isGeneral(String value, int min)
  • 给定范围的
    isGeneral(String value, int min, int max)
  • 数字
    isNumber
  • 给定范围的数字
    isBetween(Number value, Number min, Number max)
  • 纯字母
    isLetter
  • 大小写
    isUpperCase
    isLowerCase
  • ip4
    isIpv4
  • 金额
    isMoney
  • 邮件
    isEmail
  • 手机号码
    isMobile
  • 18位身份证
    isCitizenId
  • 邮编
    isZipCode
  • 出生年月日
    isBirthday
  • URL
    isUrl
  • 汉字
    isChinese
  • 汉字,字母,数字和下划线
    isGeneralWithChinese
  • mac地址
    isMac
  • 中国车牌
    isPlateNumber
  • uuid
    isUUID

身份证工具

TestIdCard.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package cn.how2j.test;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

public class TestIdCard {

@Test
@Comment("身份证校验器")
public void test1() {
String id15 = "510108871125243";
p3("15位身份证号码",id15);
p3("判断是否有效",IdcardUtil.isValidCard(id15));
p3("转换为18位身份证号码",IdcardUtil.convert15To18(id15));

p3("获取生日",IdcardUtil.getBirthByIdCard(id15));
p3("获取年龄",IdcardUtil.getAgeByIdCard(id15));
p3("获取出生年",IdcardUtil.getYearByIdCard(id15));
p3("获取出生月",IdcardUtil.getMonthByIdCard(id15));
p3("获取出生天",IdcardUtil.getDayByIdCard(id15));
p3("获取性别",IdcardUtil.getGenderByIdCard(id15));
p3("获取省份",IdcardUtil.getProvinceByIdCard(id15));

}

private String preComment = null;

private void c(String msg) {
System.out.printf("\t备注:%s%n", msg);
}

private void p1(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format1");
}

private void p2(String type1, Object value1, String type2, Object value2) {
p(type1, value1, type2, value2, "format2");
}

private void p3(String type1, Object value1) {
p(type1, value1, "", "", "format3");
}

private void p(String type1, Object value1, String type2, Object value2, String format) {
try {
throw new Exception();
} catch (Exception e) {

String methodName = getTestMethodName(e.getStackTrace());
Method m = ReflectUtil.getMethod(this.getClass(), methodName);
Comment annotation = m.getAnnotation(Comment.class);
if (null != annotation) {
String comment = annotation.value();
if (!comment.equals(preComment)) {
System.out.printf("%n%s 例子: %n%n", comment);
preComment = comment;
}

}
}
int padLength = 12;
type1 = StrUtil.padEnd(type1, padLength, Convert.toSBC(" ").charAt(0));
type2 = StrUtil.padEnd(type2, padLength, Convert.toSBC(" ").charAt(0));
if ("format1".equals(format)) {
System.out.printf("\t%s的:\t\"%s\" %n\t被转换为----->%n\t%s的 :\t\"%s\" %n%n", type1, value1, type2, value2);
}
if ("format2".equals(format)) {
System.out.printf("\t基于 %s:\t\"%s\" %n\t获取 %s:\t\"%s\"%n%n", type1, value1, type2, value2);
}
if ("format3".equals(format)) {
System.out.printf("\t%s:\t\"%s\" %n\t%n", type1, value1);

}
}

private String getTestMethodName(StackTraceElement[] stackTrace) {
for (StackTraceElement se : stackTrace) {
String methodName = se.getMethodName();
if (methodName.startsWith("test"))
return methodName;
}
return null;
}

@Target({ METHOD, TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Comment {
String value();
}
}
王方钢 / Kenny Wang wechat
王方钢 | 智叟网络
0%