hutool中的threadutil-尊龙游戏旗舰厅官网
hutool是一个java工具包,它帮助我们简化每一行代码,避免重复造轮子。如果你有需要用到某些工具方法的时候,不妨在hutool里面找找,可能就有。本文将对hutool中的常用工具类和方法进行介绍。9 n, v c0 |" i$ l
一、简介. c; v) d: q8 c" {
0 j2 p" f, }, [9 y3 f% s5 j一个java基础工具类,对文件、流、加密解密、转码、正则、线程、xml等jdk方法进行封装,组成各种util工具类,同时提供以下组件:u9 v9 v- w! `, o& z# p9 u
8 w/ s0 u* r8 w
hutool-core 核心,包括bean操作、日期、各种util等% v" c9 m& l& u/ s, f* x5 h5 d
hutool-aop jdk动态代理封装,提供非ioc下的切面支持 e. ~# w" h4 h: z$ _
hutool-bloomfilter 布隆过滤,提供一些hash算法的布隆过滤
3 e& q- u3 z6 v0 ^3 m
hutool-cache 缓存
! q6 n* w1 f) e
hutool-cron 定时任务模块,提供类crontab表达式的定时任务
! a, ~& q8 x8 h) @8 v7 r
hutool-crypto 加密解密模块
; u o$ d w x9 g% f' ^
hutool-db jdbc封装后的数据操作,基于activerecord思想
' s9 \1 y- h' i# _
hutool-dfa 基于dfa模型的多关键字查找
: h" }" g- h" b- ?: ^; s
hutool-extra 扩展模块,对第三方封装(模板引擎、邮件等) b0 `- @7 j& _) {' {* _
hutool-http 基于httpurlconnection的http客户端封装. t1 b u- _# ]& z4 g- j
hutool-log 自动识别日志实现的日志门面1 w& u* j! d( f- `6 l- n
hutool-script 脚本执行封装,例如javascript
" t: z1 `7 [2 @( \1 k
hutool-setting 功能更强大的setting配置文件和properties封装
2 f4 `; v: d4 d/ z' f3 ~( a
hutool-system 系统参数调用封装(jvm信息等)
9 n- t9 y0 l a4 v
hutool-json json实现
! k2 n) _' i v8 a
hutool-captcha 图片验证码实现( h5 f6 p1 m7 {, q9 h' u二、安装( r8 m7 d! q" y4 l& i, k
2 t8 @! }3 t/ |. w4 k
maven项目在pom.xml添加以下依赖即可:
p7 x0 \ s: z2 r7 q cn.hutool hutool-all 5.2.2三、常用工具类
4 y; q ~& v) j# p5 w# {0 h d; s! [* r* j5 u* q7 ~4 k
1. dateutil
% f1 q* i& d% u% p9 m8 d8 g, p5 g
4 s% g) |; k' f) p& i$ | y' t日期时间工具类,定义了一些常用的日期时间操作方法。( s1 d$ l) q m2 i9 y3 n% y, b
date、long、calendar之间的相互转换9 `" v2 x a, @
3 t l: x7 r% z% m2 h//当前时间date date = dateutil.date();//当前时间date date2 = dateutil.date(calendar.getinstance());//当前时间date date3 = dateutil.date(system.currenttimemillis());//当前时间字符串,格式:yyyy-mm-dd hh:mm:ssstring now = dateutil.now();//当前日期字符串,格式:yyyy-mm-ddstring today= dateutil.today();字符串转日期
9 e9 v* _3 a- g' _! k, `0 [! z5 g) j( e8 i2 x
dateutil.parse方法会自动识别一些常用格式,包括:
t. j2 x" k& g; x [7 }% j6 i, k2 r7 e8 z
yyyy-mm-dd hh:mm:ss2 b4 q! c2 z w, x8 j
yyyy-mm-dd& x! @6 r6 b5 {3 n1 n9 [- o* v9 @4 q
hh:mm:ss
( v2 b- j7 f( f h
yyyy-mm-dd hh:mm/ `! y5 l. h( n; m/ q
yyyy-mm-dd hh:mm:ss.sss
1 m7 y, }/ l: v z! a7 s% ~string datestr = "2020-03-01";date date = dateutil.parse(datestr);我们也可以使用自定义日期格式转化:
" x* b' x7 a4 t' |string datestr = "2020/03/02";date date = dateutil.parse(datestr, "yyyy/mm/dd");格式化日期输出* |: m& t9 c0 m; c1 a) k/ y
: x y* e. z7 j3 `
//结果 2020/03/01string format = dateutil.format(date, "yyyy/mm/dd");//常用格式的格式化string formatdate = dateutil.formatdate(date);string formatdatetime = dateutil.formatdatetime(date);string formattime = dateutil.formattime(date);获取date对象的某个部分
6 f- i2 w3 x0 y! o o# l2 _' ~/ m# j6 z! s4 \
//获得年的部分int year = dateutil.year(date);//获得月份,从0开始计数int month = dateutil.month(date);//获得月份,从0开始计数month monthenum = dateutil.monthenum(date);//获得日int dayofmonth = dateutil.dayofmonth(date);//获得星期数,从周日算起int dayofweek = dateutil.dayofweek(date);//获得星期枚举week dayofweekenum = dateutil.dayofweekenum(date);开始和结束时间) b* @/ q7 i& h) d% o
1 ~% p$ q* i3 p& ~5 b- ?5 s) {
有的时候我们需要获得每天的开始时间、结束时间,每月的开始和结束时间等等,dateutil也提供了相关方法:2 y& s' h% f2 n: b5 o6 b f, z1 l
//一天的开始,结果:2020-03-01 00:00:00date beginofday = dateutil.beginofday(date);//一天的结束,结果:2020-03-01 23:59:59date endofday = dateutil.endofday(date);日期时间偏移
- k' p" e: c7 l6 y2 c' a% p
' v m' l4 _& v$ |& a日期或时间的偏移指针对某个日期增加或减少分、小时、天等等,达到日期变更的目的。hutool也针对其做了大量封装
0 p( s# g p i' w5 y& v% o# s9 [$ [date newdate = dateutil.offset(date, datefield.day_of_month, 2);datetime newdate2 = dateutil.offsetday(date, 3);datetime newdate3 = dateutil.offsethour(date, -3);针对当前时间,提供了简化的偏移方法(例如昨天、上周、上个月等):% e4 f i% b. ?' \# n3 s
//昨天dateutil.yesterday()//明天dateutil.tomorrow()//上周dateutil.lastweek()//下周dateutil.nextweek()//上个月dateutil.lastmonth()//下个月dateutil.nextmonth()日期时间差, p: {% e3 p4 c: b2 e
& s& c' k* j- c3 x; u7 v( ?有时候我们需要计算两个日期之间的时间差(相差天数、相差小时数等等),hutool将此类方法封装为between方法:
b1 j s6 n; a3 b {% }long betweenday = dateutil.between(date1, date2, dateunit.day);计时器: k$ s# a9 _5 v$ u) y: s. [
- z8 d# x: k- h/ u: b* o0 `' i计时器用于计算某段代码或过程花费的时间- c2 c$ d& z* n! g
timeinterval timer = dateutil.timer();//---------------------------------//-------这是执行过程//---------------------------------timer.interval();//花费毫秒数timer.intervalrestart();//返回花费时间,并重置开始时间timer.intervalminute();//花费分钟数其它! u- `: q y4 g* l' p) y
) m( f6 r& k5 a1 x1 i' ?//年龄dateutil.ageofnow("1993-03-01");//是否闰年dateutil.isleapyear(2017);2. convert
; d( x. ]% m) |: d- l* ?! t# n; w' i6 a: m$ } a5 a
类型转换工具类,用于各种类型数据的转换。里面封装了针对java常见类型的转换,用于简化类型转换。convert类中大部分方法为toxxx,参数为object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultvalue用于在转换失败时返回一个默认值。
% y6 d0 o4 a8 s* u( `7 f/ a6 {java常见类型转换
, f- l5 f1 u. ]9 p5 ^! w q: k5 i5 p# b: s& _
8 n b0 m7 d$ p! n& y- |
转换为字符串:
# @' {- ^* t: e* m3 @9 k5 n- b- hint a = 1;//astr为"1"string astr = convert.tostr(a);long[] b = {1,2,3,4,5};//bstr为:"[1, 2, 3, 4, 5]"string bstr = convert.tostr(b);" b. {8 w8 o8 o8 m5 w8 p; w2 m
转换为指定类型数组:
8 i o" j. {1 }string[] b = { "1", "2", "3", "4" };//结果为integer数组integer[] intarray = convert.tointarray(b);long[] c = {1,2,3,4,5};//结果为integer数组integer[] intarray2 = convert.tointarray(c);1 y8 z: e- a- \0 `/ c3 h
转换为日期对象:. j0 o# u# @/ \" z3 o" wstring a = "2020-03-01";date value = convert.todate(a);- p) |" z8 a h2 @9 h$ }/ v
转换为集合
5 v' u7 ?6 }0 ~; ^object[] a = {"a", "你", "好", "", 1};list list = convert.convert(list.class, a);//从4.1.11开始可以这么用list list = convert.tolist(a);其它类型转换* y/ u: e' \' _- ^; q" @% i! g
; g; ?; g, t o( q' u$ a# {. h6 d8 d' ?
标准类型! c z/ e4 b; w6 q通过convert.convert(class, object)方法可以将任意类型转换为指定类型,hutool中预定义了许多类型转换,例如转换为uri、url、calendar等等。
0 |( g) g ^2 y3 e2 x, ~& u; {; n o* |1 ?4 [5 q1 h
泛型类型0 a3 a, m q0 g |8 u8 s5 n: {通过convert(typereference reference, object value)方法,自行new一个typereference对象可以对嵌套泛型进行类型转换。例如,我们想转换一个对象为list类型,此时传入的标准class就无法满足要求,此时我们可以这样:
% i" l2 x2 |4 d3 i' j; `/ \object[] a = { "a", "你", "好", "", 1 };list list = convert.convert(new typereference() {}, a);通过typereference实例化后制定泛型类型,即可转换对象为我们想要的目标类型。9 o) ], ~; v! f3 k% u- y
半角和全角转换
! l* ^, p, l n. d$ s# v2 q5 d6 o e5 d
在很多文本的统一化中这两个方法非常有用,主要对标点符号的全角半角转换。
/ @! p h. b3 z: p9 v1 k半角转全角:$ a1 {1 c" [: a- {6 a1 z7 b" a
string a = "123456789,$()?!:;";//结果为:"123456789,$()?!:;"string sbc = convert.tosbc(a);全角转半角:
j5 j6 @1 t5 x/ {string a = "123456789,$()?!:;";//结果为"123456789,$()?!:;"string dbc = convert.todbc(a);16进制(hex); c/ g- [9 o& c x \" e" q. h5 [
3 f# f! w, u2 w
在很多加密解密,以及中文字符串传输(比如表单提交)的时候,会用到16进制转换,就是hex转换,为此hutool中专门封装了hexutil工具类,考虑到16进制转换也是转换的一部分,因此将其方法也放在convert类中,便于理解和查找,使用同样非常简单:
: q8 p; s9 |$ y6 {转为16进制(hex)字符串8 z6 n3 i- k9 p9 f* h, d. w
string a = "字符串";string hex = convert.tohex(a, charsetutil.charset_utf_8);将16进制(hex)字符串转为普通字符串:
, s4 e0 z: k% v$ i- gstring hex = "e5ad97e7aca6e4b8b2";string raw = convert.hextostr(hex, charsetutil.charset_utf_8);因为字符串牵涉到编码问题,因此必须传入编码对象,此处使用utf-8编码。 tohex方法同样支持传入byte[],同样也可以使用hextobytes方法将16进制转为byte[]
j7 y* j1 b6 w& x( m* o; [1 vunicode和字符串转换
- {8 l5 q$ l& m& t/ w" l
/ r! a k4 ~7 p3 b# g q6 q与16进制类似,convert类同样可以在字符串和unicode之间轻松转换: p2 t' g: y) p5 m, y p
string unicode = convert.strtounicode(a);string raw = convert.unicodetostr(unicode);编码转换0 \8 _- v* g4 [
7 e( n9 l5 u7 ], z2 y! @2 m
在接收表单的时候,我们常常被中文乱码所困扰,其实大多数原因是使用了不正确的编码方式解码了数据。于是convert.convertcharset方法便派上用场了,它可以把乱码转为正确的编码方式:v. r: e' e7 w: t
string a = "我不是乱码";//转换后result为乱码string result = convert.convertcharset(a, charsetutil.utf_8, charsetutil.iso_8859_1);string raw = convert.convertcharset(result, charsetutil.iso_8859_1, "utf-8");assert.assertequals(raw, a);时间单位转换
?- [3 i$ b# f$ f. t
2 \) z% q) w$ y/ i0 nconvert.converttime方法主要用于转换时长单位,比如一个很大的毫秒,我想获得这个毫秒数对应多少分:3 _3 p4 q/ o. @
long a = 4535345;//结果为:75long minutes = convert.converttime(a, timeunit.milliseconds, timeunit.minutes);金额大小写转换
j8 s. g& s8 j# f, o& k# o6 p j* `; l f3 k' z
面对财务类需求,convert.digittochinese将金钱数转换为大写形式:
6 [( k6 t) g) m3 |, g, l9 d! ]* bdouble money = 1234.56;//结果为:"壹仟贰佰叁拾肆元伍角陆分"string digituppercase = convert.digittochinese(a);注意 转换为大写只能精确到分(小数点儿后两位),之后的数字会被忽略。% ] }& a* z7 m/ f* }原始类和包装类转换
, l1 c1 |* t0 m# s, ^6 f5 o4 v. e, g9 w8 }2 x, a* k" m
有的时候,我们需要将包装类和原始类相互转换(比如integer.classs 和 int.class),这时候我们可以:
/ k$ d, w) u- t//去包装class wrapclass = integer.class;//结果为:int.classclass unwraped = convert.unwrap(wrapclass);//包装class primitiveclass = long.class;//结果为:long.classclass wraped = convert.wrap(primitiveclass);3. strutil _5 f r' @2 v7 c
; a. u! f4 p( a# y' m1 ~
字符串工具类,定义了一些常用的字符串操作方法。/ h& ?$ l' k( a; z* z2 l8 p
hasblank、hasempty方法% m) s u1 m' n% h0 i
8 q1 b* i8 s7 m6 p# e" ?
就是给定一些字符串,如果一旦有空的就返回true,常用于判断好多字段是否有空的(例如web表单数据)。7 k& d" s* c ~# k
这两个方法的区别是hasempty只判断是否为null或者空字符串(""),hasblank则会把不可见字符也算做空,isempty和isblank同理。
2 y {: e% m \removeprefix、removesuffix方法/ l# p v% p% t7 o( k
8 w8 l' r$ ~0 ~- [* l3 e1 p这两个是去掉字符串的前缀后缀的,例如去个文件名的扩展名啥。
; g, q& f3 e/ v) b0 l0 `: hstring filename = strutil.removesuffix("pretty_girl.jpg", ".jpg") //filename -> pretty_girl还有忽略大小写的removeprefixignorecase和removesuffixignorecase都比较实用。- ?. h w; d' h6 ?- c3 q* g; n2 c
sub方法1 k8 e3 n4 v: y2 c f9 j2 }
/ s0 x% j4 c. [- t5 ?substring方法越界会报异常,得自己判断,sub把各种情况判断都加进来了,而且index的位置还支持负数,-1表示最后一个字符,如果不小心把第一个位置和第二个位置搞反了,也会自动修正
/ a4 u# n& a3 }( j7 i4 istring str = "abcdefgh";string strsub1 = strutil.sub(str, 2, 3);string strsub2 = strutil.sub(str, 2, -3); string strsub3 = strutil.sub(str, 3, 2); format方法
" @0 t5 h# w/ o1 v7 d* [! x; _% w8 t( w, p
string template = "{}和{}";string str = strutil.format(template, "我", "你");参数是object类型,传别的类型会自动调用tostring()方法。
7 k/ ~8 j. }1 d* n4. numberutil
! q m: q4 [/ v. p% q/ l2 i l ^ k0 _/ h) t
数字处理工具类,可用于各种类型数字的加减乘除操作及判断类型。
* m% o( c1 f5 h wdouble n1 = 1.234;double n2 = 1.234;double result;//对float、double、bigdecimal做加减乘除操作result = numberutil.add(n1, n2);result = numberutil.sub(n1, n2);result = numberutil.mul(n1, n2);result = numberutil.div(n1, n2);//保留两位小数bigdecimal roundnum = numberutil.round(n1, 2);string n3 = "1.234";//判断是否为数字、整数、浮点数numberutil.isnumber(n3);numberutil.isinteger(n3);numberutil.isdouble(n3);5. beanutil
, w2 j3 e8 k$ c/ k% x1 b' g q1 z% `3 e: h' x
javabean的工具类,可用于map与javabean对象的互相转换以及对象属性的拷贝。
7 d) n4 k% e6 x1 ^8 v& {/ j1 nmap转bean; q% b7 l4 o8 h/ h) t
& p, a7 a. i1 a% t, k% `7 ^: v提供了map对象键值对注入bean,其方法有:: e# i. s7 o( [8 u" z5 m
" f; h) d) z% c
beanutil.fillbeanwithmap 使用map填充bean4 j/ q! n$ r3 ehashmap map = collutil.newhashmap();map.put("name", "joe");map.put("age", 12);map.put("openid", "dfdfsdfwerwer");person person = beanutil.fillbeanwithmap(map, new person(), false);" w8 m! m7 h) u1 } d: l
beanutil.fillbeanwithmapignorecase 使用map填充bean,忽略大小写
; p% e' o8 o" r, g1 h; c yhashmap map = collutil.newhashmap();map.put("name", "yxm");map.put("age", 12);map.put("openid", "dfdfsdfwerwer");person person = beanutil.fillbeanwithmapignorecase(map, new person(), false);同时提供了map转bean的方法,与fillbean不同的是,此处并不是传bean对象,而是bean类,hutool会自动调用默认构造方法创建对象。当然,前提是bean类有默认构造方法(空构造),这些方法有:6 ?* c3 q( h2 k5 c r: o
& h0 v7 }9 y3 x9 q
maptobean,maptobeanignorecase0 o, |( h: e; i2 @4 u// 设置别名,用于对应bean的字段名hashmap mapping = collutil.newhashmap();mapping.put("a_name", "name");mapping.put("b_age", "age");person person = beanutil.maptobean(map, person.class, copyoptions.create().setfieldmapping(mapping));bean转为map
a. h5 }7 g e( _, x g# x3 t1 [ o0 `8 ~, d; d) ~$ b
beanutil.beantomap方法则是将一个bean对象转为map对象。' f1 f9 n( o$ b8 e% l, [# w0 o% a; m3 ]
person person = new person();person.setage(14);person.setopenid("11213232");person.setname("测试a11");person.setsubname("sub名字");map map = beanutil.beantomap(person);bean转bean( c# e( a6 u1 b. h- p/ x
8 m! h9 e4 r( `- e4 gbean之间的转换主要是相同属性的复制,因此方法名为copyproperties,此方法支持bean和map之间的字段复制。: }5 j" o0 t3 w* l7 o' f
beanutil.copyproperties方法同样提供一个copyoptions参数用于自定义属性复制。
; q" |# i4 }$ q4 c( u" operson p1 = new person();p1.setslow(true);p1.setname("测试");p1.setsubname("sub测试");map map = maputil.newhashmap();beanutil.copyproperties(p1, map);pmsbrand brand = new pmsbrand();brand.setid(1l);brand.setname("小米");brand.setshowstatus(0);//bean转mapmap map = beanutil.beantomap(brand);//map转beanpmsbrand mapbrand = beanutil.maptobean(map, pmsbrand.class, false);//bean属性拷贝pmsbrand copybrand = new pmsbrand();beanutil.copyproperties(brand, copybrand);6. reflectutil
3 e, t. z7 b1 x6 i0 t0 b& p* o! [& y* z" c: ~0 j1 v2 o/ b
java反射工具类,可用于反射获取类的方法及创建对象。* s2 ^: d( s" t* g" z6 h( j4 c; s
//获取某个类的所有方法method[] methods = reflectutil.getmethods(pmsbrand.class);//获取某个类的指定方法method method = reflectutil.getmethod(pmsbrand.class, "getid");//使用反射来创建对象pmsbrand pmsbrand = reflectutil.newinstance(pmsbrand.class);//反射执行对象的方法reflectutil.invoke(pmsbrand, "setid", 1);7. collutil6 \/ `: u7 ]8 ?, j( p: ^
, g# b2 } i" t& x% b6 m; m( m" k0 ~5 `集合操作的工具类,定义了一些常用的集合操作。
; d/ a& `- o; s- h( e//数组转换为列表string[] array = new string[]{"a", "b", "c", "d", "e"};list list = collutil.newarraylist(array);//join:数组转字符串时添加连接符号string joinstr = collutil.join(list, ",");//将以连接符号分隔的字符串再转换为列表list splitlist = strutil.split(joinstr, ',');//创建新的map、set、listhashmap newmap = collutil.newhashmap();hashset newhashset = collutil.newhashset();arraylist newlist = collutil.newarraylist();//判断列表是否为空collutil.isempty(list);8. maputil. h0 e ^0 u0 y3 m7 e: s
% b" e$ x5 v' i2 j
map操作工具类,可用于创建map对象及判断map是否为空。& g" \& g/ e* s/ e6 z& _
//将多个键值对加入到map中map map = maputil.of(new string[][]{ {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}});//判断map是否为空maputil.isempty(map);maputil.isnotempty(map);9. annotationutil
% c6 y; r3 ~. j8 g1 {. }# z
' j, a$ x; v8 |/ j/ h; a注解工具类,可用于获取注解与注解中指定的值。4 g! e |4 k3 h: h" }, d# o
//获取指定类、方法、字段、构造器上的注解列表annotation[] annotationlist = annotationutil.getannotations(hutoolcontroller.class, false);//获取指定类型注解api api = annotationutil.getannotation(hutoolcontroller.class, api.class);//获取指定类型注解的值object annotationvalue = annotationutil.getannotationvalue(hutoolcontroller.class, requestmapping.class);10. secureutil- g8 l1 | c. |# }2 `
8 ]8 a1 f) |3 h o2 u& b加密解密工具类,可用于md5加密。
6 _, b" u/ l% y- j4 e" ?//md5加密string str = "123456";string md5str = secureutil.md5(str);logger.info("secureutil md5:{}", md5str);其他工具类# n2 o) p8 |) u
, ^; u: p- h) r8 |# q# e
hutool中的工具类很多,可以参考:https://www.hutool.cn/
; g* c) d) e8 r& p9 a9 g' [四、项目源码地址
* }8 a" y* ~( f) [# ?! b( t/ d& s" c& v
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-hutool
1 e! \4 h" y7 b4 d9 h8 f* ? i" x; l4 z6 o. w
java吧 收集整理 java论坛 www.java8.com
与50位技术专家面对面20年技术见证,附赠技术全景图总结
以上是尊龙游戏旗舰厅官网为你收集整理的hutool中的threadutil_hutool - 好用的java工具类库的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: