1.判空
1.判断对象是否为空
Java自带
判断是否为null 不为null处理逻辑
String demo="测试一段话";
Optional.of(demo).ifPresent((d)->{
System.out.println("秀儿:"+d);
});
等同于下面写法
String demo="测试一段话";
if (demo==null){
System.out.println("秀儿:"+demo);
}
hutool中方法:判断是否为null
ObjectUtil.isNull
ObjectUtil.isNotNull
注意:此方法不能判断对象中字段为空的情况,如果需要检查Bean对象中字段是否全空,请使用
BeanUtil.isEmpty
。
springboot中方法:判断是否为null
boolean isEmpty(Object obj)
示例:
Demo demo=new Demo();
boolean empty = ObjectUtils.isEmpty(demo);
System.out.println(empty);
2.判断字符串是否为空
判断字符串是否为 null,或 ""。注意,包含空白符的字符串为非空
可以选择判断对象的方法
hutool中StrUtil方法:
isEmpty()
boolean isEmpty(Object str)
判断字符串是否包含实际内容,即非仅包含空白符,也就是 Not Blank
hutool中StrUtil方法:
isBlank
、isNotBlank
springboot中StringUtils方法:
boolean hasText(CharSequence str)
3.判断集合时候为空
1.hutool中的方法
ObjectUtil.isEmpty()
CollUtil.isEmpty()
CollUtil.isNotEmpty()
2.springboot中的方法
CollectionUtils.isEmpty()
2.类型转换
1.数组->集合
String[] strings = new String[6];
Arrays.stream(strings).collect(Collectors.toList());
hutool中的方法
String[] strings = new String[6];
CollUtil.toList(strings);
springboot中的方法
String[] strings = new String[6];
List list = (List) CollectionUtils.arrayToList(strings);
2.集合->数组
List list = new ArrayList();
String[] array = list.toArray(new String[0]);
3.bean
BeanUtil.fillBean
方法是bean注入的核心方法,此方法传入一个ValueProvider接口,通过实现此接口来获得key对应的值。CopyOptions参数则提供一些注入属性的选项。
CopyOptions的配置项包括:
editable
限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类。ignoreNullValue
是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入nullignoreProperties
忽略的属性列表,设置一个属性列表,不拷贝这些属性值ignoreError
是否忽略字段注入错误可以通过CopyOptions.create()
方法创建一个默认的配置项,通过setXXX方法设置每个配置项。
ValueProvider接口需要实现两个方法:
value
方法是通过key和目标类型来从任何地方获取一个值,并转换为目标类型,如果返回值不和目标类型匹配,将会自动调用Convert.convert
方法转换。containsKey
方法主要是检测是否包含指定的key,如果不包含这个key,其对应的属性将会忽略注入。首先定义两个bean:
// Lombok注解
@Data
public class Person{
private String name;
private int age;
}
// Lombok注解
@Data
public class SubPerson extends Person {
public static final String SUBNAME = "TEST";
private UUID id;
private String subName;
private Boolean isSlow;
}
然后注入这个bean:
Person person = BeanUtil.fillBean(new Person(), new ValueProvider(){
@Override
public Object value(String key, Class valueType) {
switch (key) {
case "name":
return "张三";
case "age":
return 18;
}
return null;
}
@Override
public boolean containsKey(String key) {
//总是存在key
return true;
}
}, CopyOptions.create());
Assert.assertEquals(person.getName(), "张三");
Assert.assertEquals(person.getAge(), 18);
同时,Hutool还提供了BeanUtil.toBean
方法,此处并不是传Bean对象,而是Bean类,Hutool会自动调用默认构造方法创建对象。
基于BeanUtil.fillBean
方法Hutool还提供了Map对象键值对注入Bean,其方法有:
BeanUtil.fillBeanWithMap
使用Map填充beanHashMap map = CollUtil.newHashMap();
map.put("name", "Joe");
map.put("age", 12);
map.put("openId", "DFDFSDFWERWER");
SubPerson person = BeanUtil.fillBeanWithMap(map, new SubPerson(), false);
BeanUtil.fillBeanWithMapIgnoreCase
使用Map填充bean,忽略大小写HashMap map = CollUtil.newHashMap();
map.put("Name", "Joe");
map.put("aGe", 12);
map.put("openId", "DFDFSDFWERWER");
SubPerson person = BeanUtil.fillBeanWithMapIgnoreCase(map, new SubPerson(), false);
同时提供了map转bean的方法,与fillBean不同的是,此处并不是传Bean对象,而是Bean类,Hutool会自动调用默认构造方法创建对象。当然,前提是Bean类有默认构造方法(空构造),这些方法有:
1. BeanUtil.toBean
HashMap map = CollUtil.newHashMap();
map.put("a_name", "Joe");
map.put("b_age", 12);
// 设置别名,用于对应bean的字段名
HashMap mapping = CollUtil.newHashMap();
mapping.put("a_name", "name");
mapping.put("b_age", "age");
Person person = BeanUtil.toBean(map, Person.class, CopyOptions.create().setFieldMapping(mapping));
2. BeanUtil.toBeanIgnoreCase
HashMap map = CollUtil.newHashMap();
map.put("Name", "Joe");
map.put("aGe", 12);
Person person = BeanUtil.toBeanIgnoreCase(map, Person.class, false);
bean->map
BeanUtil.beanToMap
方法则是将一个Bean对象转为Map对象。
SubPerson person = new SubPerson();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试A11");
person.setSubName("sub名字");
Map map = BeanUtil.beanToMap(person);
Bean转Bean
Bean之间的转换主要是相同属性的复制,因此方法名为copyProperties
,此方法支持Bean和Map之间的字段复制。
BeanUtil.copyProperties
方法同样提供一个CopyOptions
参数用于自定义属性复制。
SubPerson p1 = new SubPerson();
p1.setSlow(true);
p1.setName("测试");
p1.setSubName("sub测试");
Map map = MapUtil.newHashMap();
BeanUtil.copyProperties(p1, map);
Alias注解
5.x的Hutool中增加了一个自定义注解:@Alias
,通过此注解可以给Bean的字段设置别名。
首先我们给Bean加上注解:
// Lombok注解
@Getter
@Setter
public static class SubPersonWithAlias {
@Alias("aliasSubName")
private String subName;
private Boolean slow;
SubPersonWithAlias person = new SubPersonWithAlias();
person.setSubName("sub名字");
person.setSlow(true);
// Bean转换为Map时,自动将subName修改为aliasSubName
Map map = BeanUtil.beanToMap(person);
// 返回"sub名字"
map.get("aliasSubName")
同样Alias注解支持注入Bean时的别名:
Map map = MapUtil.newHashMap();
map.put("aliasSubName", "sub名字");
map.put("slow", true);
SubPersonWithAlias subPersonWithAlias = BeanUtil.mapToBean(map, SubPersonWithAlias.class, false);
// 返回"sub名字"
subPersonWithAlias.getSubName();
3.常用方法
1.集合或者数组 字符串拼接
String.join()
2.略
4.时间处理
时间类型使用LocalDateTime
采用hutool对时间进行处理
Date、long、Calendar之间的相互转换
//当前时间
Date date = DateUtil.date();
//当前时间
Date date2 = DateUtil.date(Calendar.getInstance());
//当前时间
Date date3 = DateUtil.date(System.currentTimeMillis());
//当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
String now = DateUtil.now();
//当前日期字符串,格式:yyyy-MM-dd
String today= DateUtil.today();
字符串转日期
DateUtil.parse
方法会自动识别一些常用格式,包括:
yyyy-MM-dd HH:mm:ss
- yyyy/MM/dd HH:mm:ss
- yyyy.MM.dd HH:mm:ss
- yyyy年MM月dd日 HH时mm分ss秒
- yyyy-MM-dd
- yyyy/MM/dd
- yyyy.MM.dd
- HH:mm:ss
- HH时mm分ss秒
- yyyy-MM-dd HH:mm
- yyyy-MM-dd HH:mm:ss.SSS
- yyyyMMddHHmmss
- yyyyMMddHHmmssSSS
- yyyyMMdd
- EEE, dd MMM yyyy HH:mm:ss z
- EEE MMM dd HH:mm:ss zzz yyyy
- yyyy-MM-dd'T'HH:mm:ss'Z'
- yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
- yyyy-MM-dd'T'HH:mm:ssZ
- yyyy-MM-dd'T'HH:mm:ss.SSSZ
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);
我们也可以使用自定义日期格式转化:
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");
格式化日期输
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);
//结果 2017/03/01
String format = DateUtil.format(date, "yyyy/MM/dd");
//常用格式的格式化,结果:2017-03-01
String formatDate = DateUtil.formatDate(date);
//结果:2017-03-01 00:00:00
String formatDateTime = DateUtil.formatDateTime(date);
//结果:00:00:00
String formatTime = DateUtil.formatTime(date);
获取Date对象的某个部分
Date date = DateUtil.date();
//获得年的部分
DateUtil.year(date);
//获得月份,从0开始计数
DateUtil.month(date);
//获得月份枚举
DateUtil.monthEnum(date);
//.....
开始和结束时间
有的时候我们需要获得每天的开始时间、结束时间,每月的开始和结束时间等等,DateUtil也提供了相关方法:
String dateStr = "2017-03-01 22:33:23";
Date date = DateUtil.parse(dateStr);
//一天的开始,结果:2017-03-01 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);
//一天的结束,结果:2017-03-01 23:59:59
Date endOfDay = DateUtil.endOfDay(date);
日期时间偏移
日期或时间的偏移指针对某个日期增加或减少分、小时、天等等,达到日期变更的目的。Hutool也针对其做了大量封装
String dateStr = "2017-03-01 22:33:23";
Date date = DateUtil.parse(dateStr);
//结果:2017-03-03 22:33:23
Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);
//常用偏移,结果:2017-03-04 22:33:23
DateTime newDate2 = DateUtil.offsetDay(date, 3);
//常用偏移,结果:2017-03-01 19:33:23
DateTime newDate3 = DateUtil.offsetHour(date, -3);
针对当前时间,提供了简化的偏移方法(例如昨天、上周、上个月等):
//昨天
DateUtil.yesterday()
//明天
DateUtil.tomorrow()
//上周
DateUtil.lastWeek()
//下周
DateUtil.nextWeek()
//上个月
DateUtil.lastMonth()
//下个月
DateUtil.nextMonth()
日期时间差
有时候我们需要计算两个日期之间的时间差(相差天数、相差小时数等等),Hutool将此类方法封装为between方法:
String dateStr1 = "2017-03-01 22:33:23";
Date date1 = DateUtil.parse(dateStr1);
String dateStr2 = "2017-04-01 23:33:23";
Date date2 = DateUtil.parse(dateStr2);
//相差一个月,31天
long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
格式化时间差
有时候我们希望看到易读的时间差,比如XX天XX小时XX分XX秒,此时使用DateUtil.formatBetween
方法:
//Level.MINUTE表示精确到分
String formatBetween = DateUtil.formatBetween(between, Level.MINUTE);
//输出:31天1小时
Console.log(formatBetween);
星座和属相
// "摩羯座"
String zodiac = DateUtil.getZodiac(Month.JANUARY.getValue(), 19);
// "狗"
String chineseZodiac = DateUtil.getChineseZodiac(1994);
其它
//年龄
DateUtil.ageOfNow("1990-01-30");
//是否闰年
DateUtil.isLeapYear(2017);
5.数字处理
使用hutool工具
加减乘除
NumberUtil.add
针对数字类型做加法NumberUtil.sub
针对数字类型做减法NumberUtil.mul
针对数字类型做乘法NumberUtil.div
针对数字类型做除法,并提供重载方法用于规定除不尽的情况下保留小数位数和舍弃方式。
以上四种运算都会将double转为BigDecimal后计算,解决float和double类型无法进行精确计算的问题。这些方法常用于商业计算。
保留小数
保留小数的方法主要有两种:
NumberUtil.round
方法主要封装BigDecimal中的方法来保留小数,返回BigDecimal,这个方法更加灵活,可以选择四舍五入或者全部舍弃等模式。
double te1=123456.123456;
double te2=123456.128456;
Console.log(round(te1,4));//结果:123456.1235
Console.log(round(te2,4));//结果:123456.1285
NumberUtil.roundStr
方法主要封装String.format
方法,舍弃方式采用四舍五入。
double te1=123456.123456;
double te2=123456.128456;
Console.log(roundStr(te1,2));//结果:123456.12
Console.log(roundStr(te2,2));//结果:123456.13
decimalFormat
针对 DecimalFormat.format
进行简单封装。按照固定格式对double或long类型的数字做格式化操作。
long c=299792458;//光速
String format = NumberUtil.decimalFormat(",###", c);//299,792,458
格式中主要以 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。
- 0 -> 取一位整数
- 0.00 -> 取一位整数和两位小数
- 00.000 -> 取两位整数和三位小数
- # -> 取所有整数部分
- #.##% -> 以百分比方式计数,并取两位小数
- #.#####E0 -> 显示为科学计数法,并取五位小数
- ,### -> 每三位以逗号进行分隔,例如:299,792,458
- 光速大小为每秒,###米 -> 将格式嵌入文本
关于格式的更多说明,请参阅:Java DecimalFormat的主要功能及使用方法
是否为数字
NumberUtil.isNumber
是否为数字NumberUtil.isInteger
是否为整数NumberUtil.isDouble
是否为浮点数NumberUtil.isPrimes
是否为质数
随机数
NumberUtil.generateRandomNumber
生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。NumberUtil.generateBySet
生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。
整数列表
NumberUtil.range
方法根据范围和步进,生成一个有序整数列表。 NumberUtil.appendRange
将给定范围内的整数添加到已有集合中
其它
NumberUtil.factorial
阶乘NumberUtil.sqrt
平方根NumberUtil.divisor
最大公约数NumberUtil.multiple
最小公倍数NumberUtil.getBinaryStr
获得数字对应的二进制字符串NumberUtil.binaryToInt
二进制转intNumberUtil.binaryToLong
二进制转longNumberUtil.compare
比较两个值的大小NumberUtil.toStr
数字转字符串,自动并去除尾小数点儿后多余的0
6.文件处理
hutool工具
FileUtil类包含以下几类操作工具:
在FileUtil中,我努力将方法名与Linux相一致,例如创建文件的方法并不是createFile,而是touch
,这种统一对于熟悉Linux的人来说,大大提高了上手速度。当然,如果你不熟悉Linux,那FileUtil工具类的使用则是在帮助你学习Linux命令。这些类Linux命令的方法包括:
ls
列出目录和文件touch
创建文件,如果父目录不存在也自动创建mkdir
创建目录,会递归创建每层目录del
删除文件或目录(递归删除,不判断是否为空),这个方法相当于Linux的delete命令copy
拷贝文件或目录
这些方法提供了人性化的操作,例如touch
方法,在创建文件的情况下会自动创建上层目录(我想对于使用者来说这也是大部分情况下的需求),同样mkdir
也会创建父目录。
需要注意的是,
del
方法会删除目录而不判断其是否为空,这一方面方便了使用,另一方面也可能造成一些预想不到的后果(比如拼写错路径而删除不应该删除的目录),所以请谨慎使用此方法。
关于FileUtil中更多工具方法,请参阅API文档。
FileReader
在JDK中,同样有一个FileReader类,但是并不如想象中的那样好用,于是Hutool便提供了更加便捷FileReader类。
//默认UTF-8编码,可以在构造中传入第二个参数做为编码
FileReader fileReader = new FileReader("test.properties");
String result = fileReader.readString();
FileReader提供了以下方法来快速读取文件内容:
readBytes
readString
readLines
同时,此类还提供了以下方法用于转换为流或者BufferedReader:
getReader
getInputStream
FileWriter
相应的,文件读取有了,自然有文件写入类,使用方式与FileReader
也类似:
FileWriter writer = new FileWriter("test.properties");
writer.write("test");
写入文件分为追加模式和覆盖模式两类,追加模式可以用append
方法,覆盖模式可以用write
方法,同时也提供了一个write方法,第二个参数是可选覆盖模式。
同样,此类提供了:
getOutputStream
getWriter
getPrintWriter
这些方法用于转换为相应的类提供更加灵活的写入操作。
SpringBoot中文件 IO工具
FileCopyUtils
// 从文件中读入到字节数组中
byte[] copyToByteArray(File in)
// 从输入流中读入到字节数组中
byte[] copyToByteArray(InputStream in)
// 从输入流中读入到字符串中
String copyToString(Reader in)
// 从字节数组到文件
void copy(byte[] in, File out)
// 从文件到文件
int copy(File in, File out)
// 从字节数组到输出流
void copy(byte[] in, OutputStream out)
// 从输入流到输出流
int copy(InputStream in, OutputStream out)
// 从输入流到输出流
int copy(Reader in, Writer out)
// 从字符串到输出流
void copy(String in, Writer out)
ResourceUtils
// 判断字符串是否是一个合法的 URL 字符串。
static boolean isUrl(String resourceLocation)
// 获取 URL
static URL getURL(String resourceLocation)
// 获取文件(在 JAR 包内无法正常使用,需要是一个独立的文件)
static File getFile(String resourceLocation)
// 文件系统资源 D:...
FileSystemResource
// URL 资源,如 file://... http://...
UrlResource
// 类路径下的资源,classpth:...
ClassPathResource
// Web 容器上下文中的资源(jar 包、war 包)
ServletContextResource
// 判断资源是否存在
boolean exists()
// 从资源中获得 File 对象
File getFile()
// 从资源中获得 URI 对象
URI getURI()
// 从资源中获得 URI 对象
URL getURL()
// 获得资源的 InputStream
InputStream getInputStream()
// 获得资源的描述信息
String getDescription()
StreamUtils
void copy(byte[] in, OutputStream out)
int copy(InputStream in, OutputStream out)
void copy(String in, Charset charset, OutputStream out)
long copyRange(InputStream in, OutputStream out, long start, long end)
byte[] copyToByteArray(InputStream in)
String copyToString(InputStream in, Charset charset)
// 舍弃输入流中的内容
int drain(InputStream in)
7.文件路径
1.某个resources下的路径
String filePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
也就是Classes下的路径
2.当前运行的tomcat的路径
String realPath = request.getSession().getServletContext().getRealPath("");
其返回值为当前运行的tomcat路径
其路径为:xxxx/xxxx/tomcat/webapps
注意:其路径为绝对路径
8.MultipartFile转文件
将spring上传的文件保存到指定位置
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Component
public class FileTool {
public void saveFile(String filePath, MultipartFile file){
File saveFile = new File(filePath);
if (!saveFile.exists()){
try {
FileUtils.touch(saveFile);
FileUtils.copyInputStreamToFile(file.getInputStream(),saveFile);
} catch (IOException e) {
throw new ServerException("文件保存出错:"+e.getMessage());
}
}
}
}