一:Java开发常用知识点基础篇

2023年 10月 12日 87.2k 0

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()
  • springboot中StringUtils方法:
    • boolean isEmpty(Object str)

    判断字符串是否包含实际内容,即非仅包含空白符,也就是 Not Blank

    hutool中StrUtil方法:

    • isBlankisNotBlank

    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: 注入null
  • ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
  • 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填充bean
  • HashMap 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 二进制转int
    • NumberUtil.binaryToLong 二进制转long
    • NumberUtil.compare 比较两个值的大小
    • NumberUtil.toStr 数字转字符串,自动并去除尾小数点儿后多余的0

    6.文件处理

    hutool工具

    FileUtil类包含以下几类操作工具:

  • 文件操作:包括文件目录的新建、删除、复制、移动、改名等
  • 文件判断:判断文件或目录是否非空,是否为目录,是否为文件等等。
  • 绝对路径:针对ClassPath中的文件转换为绝对路径文件。
  • 文件名:主文件名,扩展名的获取
  • 读操作:包括类似IoUtil中的getReader、readXXX操作
  • 写操作:包括getWriter和writeXXX操作
  • 在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)
    
  • Resource
  • // 文件系统资源 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());  
    }  
    }  
    }  
    }
    

    9.发送http请求

    10.HttpServletResponse返回数据

    11.其他

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论