Skip to content

随记

多动手,多总结。

个人常用方法整理,方便日常复制分享,都是自己封装或者搬运来的,讲究语法简洁但是效果显著

时间-获取连续时间

java
/**
 * 获取范围日期的指定连续时间
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @param amountToAdd 时间拨动数量级
 * @param unit 时间单元
 * @return
 * @author shafulin on 2021/7/6 12:08
 */
public static List<LocalDateTime> getBetweenDate(LocalDateTime startTime, LocalDateTime endTime,long amountToAdd, TemporalUnit unit){
    return getBetweenDate(startTime,endTime,amountToAdd,unit,Function.identity());
}
/**
 * 获取范围日期的指定连续时间
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @param amountToAdd 时间拨动数量级
 * @param unit 时间单元
 * @return
 * @author shafulin on 2021/7/6 12:08
 */
public static<T> List<T> getBetweenDate(LocalDateTime startTime, LocalDateTime endTime, long amountToAdd,
                                        TemporalUnit unit, Function<LocalDateTime,T> function){
    List<T> tList = new ArrayList<>();
    for (LocalDateTime startTimeTemp = startTime; startTimeTemp.isBefore(endTime) || startTimeTemp.isEqual(endTime);startTimeTemp = startTimeTemp.plus(amountToAdd, unit)) {
        tList.add(function.apply(startTimeTemp));
    }
    return tList;
}

调用示例

java
package top.zlhy7;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * @author shafulin
 * @date 2023/4/4 21:38
 * @description 测试类
 */
public class Test1 {
    public static void main(String[] args) {
        // 获取2023-03-10到2023-04-04之间的所有日期
        LocalDateTime startLocalDateTime = LocalDateTime.of(LocalDate.of(2023, 3, 10), LocalTime.MIN);
        LocalDateTime endLocalDateTime = LocalDateTime.of(LocalDate.of(2023, 4, 4), LocalTime.MAX);
        List<String> betweenDate = RyUtools.getBetweenDate(startLocalDateTime, endLocalDateTime,
                1, ChronoUnit.DAYS, localDateTime -> localDateTime.toLocalDate().toString());
        /*
        [2023-03-10, 2023-03-11, 2023-03-12, 2023-03-13, 2023-03-14, 2023-03-15, 2023-03-16, 2023-03-17,
         2023-03-18, 2023-03-19, 2023-03-20, 2023-03-21, 2023-03-22, 2023-03-23, 2023-03-24, 2023-03-25, 
         2023-03-26, 2023-03-27, 2023-03-28, 2023-03-29, 2023-03-30, 2023-03-31, 2023-04-01, 2023-04-02, 
         2023-04-03, 2023-04-04]
         */
        System.out.println(betweenDate);
        // 获取一天连续小时
        startLocalDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        endLocalDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        betweenDate = RyUtools.getBetweenDate(startLocalDateTime, endLocalDateTime,
                1, ChronoUnit.HOURS, localDateTime -> localDateTime.toLocalTime().toString());
        /*
        [00:00, 01:00, 02:00, 03:00, 04:00, 05:00, 06:00, 07:00, 08:00, 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, 17:00, 18:00, 19:00, 20:00, 21:00, 22:00, 23:00]
         */
        System.out.println(betweenDate);
    }
}

图片类-图片与base64相互转化

参考文档

java
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Optional;

/**
 * 将图片文件转换成base64字符串,参数为该图片的路径
 *
 * @param imageFile
 * @return java.lang.String
 */
public static String imageToBase64(String imageFile) {
    byte[] data = null;
    File file = new File(imageFile);
    // 读取图片字节数组
    try (InputStream in = new FileInputStream(imageFile)){
        data = IOUtils.toByteArray(in);
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 对字节数组Base64编码
    return Optional.ofNullable(data)
            // 返回Base64编码过的字节数组字符串
            .map(dataTemp -> "data:image/jpeg;base64," + new String(Base64.getEncoder().encode(dataTemp)))
            .orElse("");
}

/**
 * 将base64解码成图片并保存在传入的路径下
 * 第一个参数为base64 ,第二个参数为路径
 *
 * @param base64, imgFilePath
 * @return boolean
 */
public static boolean base64ToImage(String base64, String imgFilePath) {
    // 对字节数组字符串进行Base64解码并生成图片
    if (StringUtils.isEmpty(base64)){
        return false;
    }
    try (OutputStream out = new FileOutputStream(imgFilePath)){
        // Base64解码
        byte[] b = Base64.getDecoder().decode(base64);
        for (int i = 0; i < b.length; i++) {
            // 调整异常数据
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        out.write(b);
        out.flush();
        return true;
    } catch (Exception e) {
        return false;
    }
}
/**
 * 这个方法比较简单,推荐这个,直接传图片码就行了
 *
 */
public static void base64StringToImage(String base64String) {
    byte[] bytes1 = Base64.getDecoder().decode(base64String);
    try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes1)){
        BufferedImage bi1 = ImageIO.read(bais);
        File f1 = new File("d:/out.jpg");
        ImageIO.write(bi1, "jpg", f1);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

文件-解/压缩文件

压缩文件1

java
/**
 * 将多个文件压缩成一个zip  jdk 1.5
 *
 * @param filePath 要压缩的文件存在的路径 如:D:/TT/
 * @param fileList 要压缩的文件数组      如:d://ss.txt、D://st.txt,ss.txt
 * @param tarName  压缩后的压缩文件名称   如:all.zip
 * @return 压缩文件
 * 参考文档 :  https://blog.csdn.net/yewen1234/article/details/72629457
 */
public static File zipFile(File[] fileList, String tarName) {
    byte[] buf = new byte[1024];
    //压缩文件名
    String outFilename = Optional.ofNullable(tarName)
        .orElse(UUID.randomUUID().toString()+".zip");
    File zipFile = new File(outFilename);
    try (
        OutputStream os = new FileOutputStream(zipFile);
        ZipOutputStream out = new ZipOutputStream(os);
    ){
        int len = 0;
        for (int i = 0; i < fileList.length; i++) {
            FileInputStream fis = new FileInputStream(fileList[i]);
            out.putNextEntry(new ZipEntry(fileList[i].getName()));
            while ((len = fis.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.closeEntry();
            fis.close();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return zipFile;
}

压缩文件2

java
/**
 * 解压文件 nio方式
 * @param zipFile 压缩文件
 * @param fileList 被压缩文件列表
 * @return
 * @author shafulin on 2020/12/22 11:26
 */
public static void zipFileChannel (File zipFile, List<File> fileList) {
    //开始时间
    long beginTime = System.currentTimeMillis();
    try(
        OutputStream os = new FileOutputStream(zipFile);
        ZipOutputStream zipOut = new ZipOutputStream (os);
        WritableByteChannel writableByteChannel = Channels.newChannel(zipOut)
    ) {
        for (int i = 0; i < fileList.size(); i++) {
            try (FileChannel fileChannel = new FileInputStream(fileList.get(i)).getChannel()){
                zipOut.putNextEntry(new ZipEntry(fileList.get(i).getName()));
                fileChannel.transferTo(0,fileList.get(i).length(),writableByteChannel);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    long e = System.currentTimeMillis() - beginTime;
    log.info("压缩文件耗时 {} ms",e);
}

解压文件

java
/**
 * 解压文件
 *
 * @param folder    解压文件的路径,必须为目录
 * @param zipFile 输入的解压文件路径,例如C:/temp/foo.zip或 c:\\temp\\bar.zip
 */
public static void unzip(File folder,File zipFile){
    long s=System.currentTimeMillis();
    //解压目录不存在就创建
    if(!folder.exists()){
        folder.mkdirs();
    }
    try(
        InputStream is=new FileInputStream(zipFile);
        ZipInputStream zis=new ZipInputStream(is)
    ){
        ZipEntry ze;
        int len=0;
        byte[]buffer=new byte[2048];
        while((ze=zis.getNextEntry())!=null){
            File newFile=new File(folder.getAbsolutePath()+File.separator+ze.getName());
            if(ze.isDirectory()){
                newFile.mkdirs();
            }
            FileOutputStream fos=new FileOutputStream(newFile);
            for(;-1!=(len=zis.read(buffer));){
                fos.write(buffer,0,len);
            }
            fos.close();
        }
        zis.closeEntry();
    }catch(IOException e){
        log.warn(e.getMessage());
    }
    long e=System.currentTimeMillis()-s;
    log.debug("解压文件 {},耗时 {} ms",zipFile.getName(),e);
}

文件-读写

一次性读取全部文件内容

java
/** 
* 返回文件内容 
* @param file 加载的文件 
* @return 
*/
public static String getContent(File file){ 
    String encoding = "UTF-8"; 
    String str = null;
    Long filelength = file.length(); 
    byte[] filecontent = new byte[filelength.intValue()];
    try { 
        FileInputStream in = new FileInputStream(file);
        in.read(filecontent);
        in.close();
        str = new String(filecontent, encoding);
    } catch (Exception e) { 
        e.printStackTrace(); 
    }finally {
        return str; 
    }
}

/**
 * 读取文件方法2
 */
public static String getContent2(File file){
    try (FileInputStream fis = new FileInputStream(file)) { 
        byte[] array = new byte[(int) file.length()]; 
        fis.read(array); 
        return new String(array);
    }
}

一次性写入全部文件

java
org.apache.commons.io.FileUtils.wirteStringToFile(file,"你好世界""UTF-8");

按行读取文件

你好.txt

你好世界
不好世界
hello world
哈哈
java
//一次性读取
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
for(String line : lines){
    sb.append(line);
}
String fromFile = sb.toString();
System.out.println(fromFile);
//逐行读取
Files.lines(path,StandardCharsets.UTF_8).forEach(System.err::println);

复制文件-传统io

java
/**
 * 传统方式
 * @param sourcePath
 * @param destPath
 * @return
 * @author shafulin on 2020/12/22 14:23
 */
private static void traditionalCopy(String sourcePath, String destPath) throws Exception {
    File source = new File(sourcePath);
    File dest = new File(destPath);
    if (!dest.exists()) {
        dest.createNewFile();
    }
    try(
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
    ){
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

复制文件-nio方式

java
/**
 * nio方式
 * @param sourcePath
 * @param destPath
 * @return
 * @author shafulin on 2020/12/22 14:24
 */
private static void nioCopy(String sourcePath, String destPath) throws Exception {
    File source = new File(sourcePath);
    File dest = new File(destPath);
    if (!dest.exists()) {
        dest.createNewFile();
    }
    try(
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
    ){
        FileChannel sourceCh = fis.getChannel();
        FileChannel destCh = fos.getChannel();
        destCh.transferFrom(sourceCh, 0, sourceCh.size());
    }catch (Exception e){
        e.printStackTrace();
    }
}

复制文件-nio映射文件方式

java
/**
 * 利用NIO文件内存映射及文件通道实现文件拷贝耗时
 * @param sourcePath
 * @param destPath
 * @return
 * @author shafulin on 2020/12/22 14:26
 */
public static void nioCopy2(String sourcePath, String destPath) throws Exception {
    File source = new File(sourcePath);
    File dest = new File(destPath);
    if (!dest.exists()) {
        dest.createNewFile();
    }
    try(
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
    ){
        FileChannel sourceCh = fis.getChannel();
        FileChannel destCh = fos.getChannel();
        MappedByteBuffer mbb = sourceCh.map(FileChannel.MapMode.READ_ONLY, 0, sourceCh.size());
        destCh.write(mbb);
    }catch (Exception e){
        e.printStackTrace();
    }
}

文件重命名

java
Path path = Paths.get("E:\\FileWatch\\你好.md");
//移动策略为覆盖已存在文件
Files.move(path,path.resolveSibling("不好世界.md"), StandardCopyOption.REPLACE_EXISTING);

遍历文件树,可以打印或删除

java
public static void rmdir(Path dir) throws IOException {
    Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            //                Files.delete(file);
            System.out.println(file);
            return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            //                Files.delete(dir);
            System.out.println(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}
/**
打印效果如下
E:\FileWatch\10米波长_几何不平顺.csv   //根目录下的文件
E:\FileWatch\2020-10-31\1042681771906100127848038006785.jpg //最深的子级
E:\FileWatch\2020-10-31\1043176697368600127849076228097.jpg
E:\FileWatch\2020-10-31\1213577568524100128206422474753.jpg
E:\FileWatch\2020-10-31 //倒数第二的子级
*/

获取符合条件的目录或文件

java
//获取文件信息
Path file = Paths.get("E:\\FileWatch\\forumAnnex");
//目录不存在就创建下
if(Files.isDirectory(目录) && !Files.exists(目录)){
    Files.createDirectories(目录);
}
//获取本机文件系统
FileSystem fileSystem = FileSystems.getDefault();
//设置匹配模式,有两种 glob和regex
//全匹配,所有目录下的 tmp|txt 文件
PathMatcher pathMatcher = fileSystem.getPathMatcher("glob:**/*.{tmp,txt}");
System.out.println("***************查询目录下所有的 tmp和txt文件");
//查询所有的 tmp和txt文件
Files.walk(目录)
    .filter(pathMatcher::matches)
    .forEach(System.out::println);
System.out.println("***************查询目录下所有的 jpg文件");
//查找所有的jpg文件
pathMatcher = fileSystem.getPathMatcher("glob:**/*.jpg");
//查询所有的 jpg文件
Files.walk(目录)
    .filter(pathMatcher::matches)
    .forEach(System.out::println);
System.out.println("***************查询目录下直属的 jpg文件");
//查询目录下所有的文件目录
Files.walk(目录).forEach(System.out::println);

/*

***************查询目录下所有的 tmp和txt文件
E:\FileWatch\forumAnnex\2020-11-22\288885215632700125313206517761.txt
E:\FileWatch\forumAnnex\2020-11-23\377230484251800125498470825985.txt
E:\FileWatch\forumAnnex\2020-11-23\新建文本文档.tmp
E:\FileWatch\forumAnnex\2020-11-26\182407161762700126043988426753.txt
E:\FileWatch\forumAnnex\新建文本文档.tmp
***************查询目录下所有的 jpg文件
E:\FileWatch\forumAnnex\2020-11-22\289060262125600125313573519361.jpg
E:\FileWatch\forumAnnex\2020-11-22\289166412235300125313795817473.jpg
E:\FileWatch\forumAnnex\2020-11-22\289166413269400125313795817474.jpg
E:\FileWatch\forumAnnex\2020-11-23\376380683097000125496688181251.jpg
E:\FileWatch\forumAnnex\2020-11-27\189635290161900126059146575875.jpg
E:\FileWatch\forumAnnex\2020-11-27\189635291217100126059146575877.jpg
E:\FileWatch\forumAnnex\2020-11-27\189635291945400126059146575879.jpg
E:\FileWatch\forumAnnex\289060262125600125313573519361.jpg
E:\FileWatch\forumAnnex\289166412235300125313795817473.jpg
E:\FileWatch\forumAnnex\289166413269400125313795817474.jpg
***************查询目录下所有文件|目录
E:\FileWatch\forumAnnex
E:\FileWatch\forumAnnex\2020-11-22
*/

获取桌面路径

java
// 获取桌面路径
FileSystemView fsv = FileSystemView.getFileSystemView();
String desktop = fsv.getHomeDirectory().getPath();
String filePath = desktop + "/template.xlsx";

字符串-占位符渲染

java

/**
 * 占位符匹配正则
 */
public static final Pattern pattern = Pattern.compile("(\\#\\{.*?\\})");
/**
 * 字符串模板渲染
 * @param stringTemplate 字符串
 * @param jsonObject 参数值,只取一级
 * @return
 * @author shafulin on 2023/3/29 10:36
 */
@Override
public String stringTemplateRendering(String stringTemplate, JSONObject jsonObject){
    if(StringUtils.isBlank(stringTemplate)){
        return stringTemplate;
    }
    log.info("字符串渲染前: {}",stringTemplate);
    //正则匹配所有占位符
    Matcher matcher = pattern.matcher(stringTemplate);
    Map<String,String> replaceMap = new HashMap<>(jsonObject.size());
    while (matcher.find()) {
        //占位符记录
        String placeholder = matcher.group();
        log.info("查找到占位符:{}", placeholder);
        replaceMap.put(placeholder,jsonObject.getString(placeholder.replaceAll("\\#\\{|\\}", "")));
    }
    if(MapUtils.isEmpty(replaceMap)){
        return stringTemplate;
    }
    for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
        stringTemplate = stringTemplate.replace(entry.getKey(),
                                                StringUtils.isEmpty(entry.getValue())?
                                                StringUtils.EMPTY:entry.getValue());
    }
    log.info("字符串渲染后: {}",stringTemplate);
    return stringTemplate;
}

ip当做数字存储

java
/**
 * @author shafulin
 * @date 2021/9/28 11:00
 * @description 如果要存ip地址,用什么数据类型比较好
 */
public class Test1 {
    /**
     * 把字符串IP转换成long
     *
     * @param ipStr 字符串IP
     * @return IP对应的long值
     */
    public static long ip2Long(String ipStr) {
        String[] ip = ipStr.split("\\.");
        return (Long.valueOf(ip[0]) << 24) + (Long.valueOf(ip[1]) << 16)
                + (Long.valueOf(ip[2]) << 8) + Long.valueOf(ip[3]);
    }

    /**
     * 把IP的long值转换成字符串
     *
     * @param ipLong IP的long值
     * @return long值对应的字符串
     */
    public static String long2Ip(long ipLong) {
        StringBuilder ip = new StringBuilder();
        ip.append(ipLong >>> 24).append(".");
        ip.append((ipLong >>> 16) & 0xFF).append(".");
        ip.append((ipLong >>> 8) & 0xFF).append(".");
        ip.append(ipLong & 0xFF);
        return ip.toString();
    }

    public static void main(String[] args) {
        System.out.println(ip2Long("192.168.0.1"));
        System.out.println(long2Ip(3232235521L));
        System.out.println(ip2Long("10.0.0.1"));
    }
}

java调用js

java
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine se = manager.getEngineByName("js");
String str = "Math.pow(2,3)";
boolean result=false;
try { 
    Double resultt = (Double) se.eval(str); 
    System.out.println(result);
} catch (ScriptException e) {
    e.printStackTrace();
}

清空列表list

java
/**
 * 清空list字段
 * @param list
 */
public static List<?> emptyListField(List<?> list,int initialCapacity){
    // 列表为空 || (列表不为空 && 列表属于空列表类型)
    boolean flag = list == null || (list != null &&
            list.getClass().toString().equals(Collections.EMPTY_LIST.getClass().toString()));
    if(flag){
        list = new ArrayList<>(initialCapacity);
    }
    list.clear();
    return list;
}
// 使用
list = emptyListField(list,1);

有趣的写法

有趣的占位符写法

一般都是n个占位符,n个参数,但是一个参数复用多次这就很好玩了,示例代码如下

java
Date date = new Date();
System.out.printf("%tY-%tm-%td %tH:%tM:%tS\n",date,date,date,date,date,date); // 2023-09-20 22:45:13
// 1$代表你的第1个参数,可以通过以下方式实现日期变量,而不是多次传递日期变量
System.out.printf("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS\n",date); // 2023-09-20 22:45:13

javadoc跳转写法

java
/*
格式:{@link 类名}
例如:{@link TransferStatusEnum}
javadoc写法,可以跳转到具体的类,用法如下
 */

/**
 * 转让状态 0不用转让,1待确认,2已确认
 * {@link TransferStatusEnum}
 */
private Integer transferStatus;

json

fastjson-json字符串转换为对象

  • 带泛型
java
# fastjson转化任意json为特定格式,带上泛型
// 使用TypeReference来指定目标类型
TypeReference<List<List<BigDecimal>>> typeRef = new TypeReference<List<List<BigDecimal>>>() {};
// 将JSON字符串转换为List<List<BigDecimal>>
List<List<BigDecimal>> coordinates = JSON.parseObject(jsonString, typeRef);

Released under the MIT License.