【Java】常用工具类方法:树形结构、获取IP、对象拷贝、File相关、雪花算法等
1、生成子孙树
/**
* 生成子孙树
*
* @param dataArray 遍历所有数据, 每个数据加到其父节点下
* @return 子孙树json
*/
public static JSONArray makeTree(JSONArray dataArray) {
List<Map<String, Object>> data = new ArrayList<>();
for (int i = 0; i < dataArray.size(); i++) {
JSONObject jsonObject = dataArray.getJSONObject(i);
Map<String, Object> map = new HashMap<>(jsonObject);
data.add(map);
}
List<Map<String, Object>> res = new ArrayList<>();
Map<Integer, Map<String, Object>> map = new HashMap<>();
// 整理数组
for (Map<String, Object> vo : data) {
map.put((Integer) vo.get("id"), vo);
}
// 查询子孙
for (Map<String, Object> vo : data) {
Integer pid = (Integer) vo.get("pid");
if (pid != 0) {
Map<String, Object> parent = map.get(pid);
if (parent != null) {
List<Map<String, Object>> children = (List<Map<String, Object>>) parent.get("children");
if (children == null) {
children = new ArrayList<>();
parent.put("children", children);
}
children.add(vo);
}
}
}
// 去除杂质
for (Map<String, Object> vo : data) {
int pid = (Integer) vo.get("pid");
if (pid == 0) {
res.add(vo);
}
}
return new JSONArray(Collections.singletonList(res));
}
2、对象序列化成JSON
/**
* 对象序列化成JSON
*/
public static JSONObject parseToUnderlineJson(Object object) {
if (object != null) {
JSONObject json = JSONObject.parseObject(JSON.toJSONString(object));
JSONObject jsonObject = new JSONObject();
for (String key : json.keySet()) {
String camelName = underscoreName(key);
jsonObject.put(camelName, json.get(key));
}
return jsonObject;
}
return null;
}
public static String underscoreName(String name) {
StringBuilder result = new StringBuilder();
if (name != null && name.length() > 0) {
result.append(name.substring(0, 1).toLowerCase());
for (int i = 1; i < name.length(); i++) {
String s = name.substring(i, i + 1);
// 在大写字母前添加下划线
if (!StringUtils.isAllLowerCase(s) && Character.isUpperCase(s.charAt(0))) {
result.append("_").append(s.toLowerCase());
} else {
result.append(s);
}
}
}
return result.toString();
}
3、获取请求的IP地址
/**
* 未知IP
*/
private static final String UNKNOWN = "unknown";
/**
* 获取请求的IP地址
*
* @param request request
* @return ip地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
4、文件相关
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.util.Arrays;
@Slf4j
public class FileUtil {
/**
* 返回文件后缀名
*
* @return 文件后缀名
*/
public static String getSuffixName(String fileName) {
if (StringUtils.isNotBlank(fileName)) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
return "";
}
/**
* 返回文件后缀名前面带.
*
* @return 文件后缀名
*/
public static String getSuffixNameWithPoint(String fileName) {
if (StringUtils.isNotBlank(fileName)) {
return fileName.substring(fileName.lastIndexOf("."));
}
return "";
}
/**
* 获取文件大小 返回 KB 保留3位小数 没有文件时返回0
*
* @param path
* 文件绝对路径
* @return Double
*/
public static Double getFileSize(String path) {
File file = new File(path);
return (double)file.length() / 1000.000;
}
/**
* 创建目录
*
* @param path
* 文件夹路径
* @return boolean
*/
public static boolean createDir(String path) {
File dir = new File(path);
return dir.getParentFile().exists() && dir.mkdir();
}
/**
* 读取到字节数组--方式1
*
* @param filePath
* 文件路径
* @return byte[]
*/
public static byte[] toByteArray(String filePath) {
File file = new File(filePath);
long fileSize = file.length();
if (fileSize > Integer.MAX_VALUE) {
log.info("file too big...");
return null;
}
FileInputStream fi = null;
byte[] buffer = new byte[0];
try {
fi = new FileInputStream(file);
buffer = new byte[(int)fileSize];
int offset = 0;
int numRead = 0;
while (offset < buffer.length && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
// 确保所有数据均被读取
if (offset != buffer.length) {
throw new IOException("Could not completely read file " + file.getName());
}
fi.close();
} catch (IOException e) {
log.error("error={}", "文件读取到字节数组错误", e);
} finally {
try {
if (fi != null) {
fi.close();
}
} catch (IOException e) {
log.error("关闭fi错误", e);
}
}
return buffer;
}
/**
* 读取到字节数组--方式2
*
* @param filePath
* 文件路径
* @return byte[]
* @throws FileNotFoundException
*/
public static byte[] toByteArrayTwo(String filePath) throws FileNotFoundException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException(filePath);
}
BufferedInputStream in = null;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream((int)f.length())) {
in = new BufferedInputStream(new FileInputStream(f));
int bufSize = 1024;
byte[] buffer = new byte[bufSize];
int len = 0;
while (-1 != (len = in.read(buffer, 0, bufSize))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
log.error("error={}", "读取到字节数组错误", e);
} finally {
closeBufferedInputStream(in);
}
return null;
}
/**
* 关闭输入流
*
* @param in
* 输入流
*/
private static void closeBufferedInputStream(BufferedInputStream in) {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
log.error("closeBufferedInputStream", e);
}
}
/**
* 读取到字节数组--方式3
*
* @param filePath
* 文件路径
* @return byte[]
* @throws IOException
* IOException
*/
public static byte[] toByteArrayThree(String filePath) throws IOException {
FileChannel fc = null;
RandomAccessFile rf = null;
try {
rf = new RandomAccessFile(filePath, "r");
fc = rf.getChannel();
MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()).load();
byte[] result = new byte[(int)fc.size()];
if (byteBuffer.remaining() > 0) {
byteBuffer.get(result, 0, byteBuffer.remaining());
}
return result;
} catch (IOException e) {
log.error("toByteArrayThree",e);
throw e;
} finally {
try {
assert rf != null;
rf.close();
assert fc != null;
fc.close();
} catch (IOException e) {
log.error("close_rf_fc",e);
}
}
}
/**
* 获取该输入流的MD5值
*
* @param is
* 输入流
* @return md5
*/
public static String getMd5Content(InputStream is) {
StringBuilder md5 = new StringBuilder();
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = is.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
} ;
byte[] mdbytes = md.digest();
// convert the byte to hex format
for (byte mdByte : mdbytes) {
md5.append(Integer.toString((mdByte & 0xff) + 0x100, 16).substring(1));
}
} catch (Exception e) {
log.error("error={}", "获取文件md5值失败",e);
}
return md5.toString();
}
/**
* 获取该文件的MD5值
*
* @param file
* 文件
* @return MD5
*/
public static String getFileMd5Content(File file) {
String md5 = "";
try (FileInputStream fis = new FileInputStream(file)) {
md5 = getMd5Content(fis);
} catch (IOException e) {
log.error("error={}", "获取文件md5值失败",e);
}
return md5;
}
/**
* 得到文件md5值
*
* @param file
* 文件
* @return md5String
*/
public static String getFileMd5(File file) {
String md5File = "";
try (FileInputStream fileInputStream = new FileInputStream(file);){
md5File = MessageDigestUtil.md5Encode(Arrays.toString(IOUtils.toByteArray(fileInputStream)));
} catch (IOException e) {
log.error("error={}", "获取文件md5值失败",e);
}
return md5File;
}
/**
* 判断文件是否存在
*
* @param filePath
* 文件路径
* @return 文件是否存在
*/
public static boolean judeFileExists(String filePath) {
File file = new File(filePath);
return file.exists();
}
}
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@Slf4j
public class MessageDigestUtil {
/**
* md5加密
*
* @param md5Str 加密字符
* @return md5加密之后的字符
*/
public static String md5Encode(String md5Str) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
log.error("md5Encode_md5",e);
return "";
}
byte[] bytes;
try {
bytes = md5Str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
log.error("md5Encode_bytes",e);
return "";
}
byte[] md5Byte = md5.digest(bytes);
StringBuffer stringBuffer = new StringBuffer();
messageDigest(md5Byte, stringBuffer);
return stringBuffer.toString();
}
private static void messageDigest(byte[] md5Byte, StringBuffer buffer) {
for (byte aMd5Byte : md5Byte) {
int val = ((int) aMd5Byte) & 0xff;
if (val < 16) {
buffer.append("0");
}
buffer.append(Integer.toHexString(val));
}
}
public static String read(BufferedReader bufferedReader) {
StringBuilder sb = new StringBuilder("");
String temp;
try {
while ((temp = bufferedReader.readLine()) != null) {
sb.append(temp);
}
} catch (IOException e) {
log.error("read",e);
}
return sb.toString();
}
/**
* 利用java原生的摘要实现SHA256加密
*
* @param str 加密后的报文
* @return 加密字符串
*/
public static String sha256Encode(String str) {
MessageDigest messageDigest;
String encodeStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
encodeStr = byte2Hex(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
log.error("sha256Encode",e);
}
return encodeStr;
}
/**
* 将byte转为16进制
*
* @param bytes byte数组
* @return 16进制字符串
*/
private static String byte2Hex(byte[] bytes) {
StringBuilder stringBuffer = new StringBuilder();
String temp = null;
for (byte aByte : bytes) {
temp = Integer.toHexString(aByte & 0xFF);
if (temp.length() == 1) {
//1得到一位的进行补0操作
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}
5、对象拷贝
import org.springframework.cglib.beans.BeanCopier;
import java.util.HashMap;
import java.util.Map;
/**
* BeanCopier工具类
*/
public class BeanCopierUtils {
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<>();
/**
*
* 将soruce对象的属性转换给target对象
* @date 2022/3/9 9:11
* @param source 需要转换的对象
* @param target 目标对象
*/
public static void copyProperties(Object source, Object target) {
BeanCopier beanCopier;
String cacheKey = source.getClass().toString() + target.getClass().toString();
if (!beanCopierCacheMap.containsKey(cacheKey)) {
synchronized (BeanCopierUtils.class) {
if (!beanCopierCacheMap.containsKey(cacheKey)) {
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
beanCopier.copy(source, target, null);
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 数据格式转换工具类
*/
public class ObjectConvertUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ObjectConvertUtils.class);
/**
* 浅克隆
*
* @param source 原对象
* @param clazz 目标对象
* @return T
* @date 2022/4/6 13:45
*/
public static <T> T clone(Object source, Class<T> clazz) {
return clone(source, clazz, true);
}
/**
*
* @date 2022/7/18 16:36
* @param source 原对象
* @param clazz 目标对象
* @param whetherAssignNull 是否赋值空值:true是 false否
* @return T
*/
public static <T> T clone(Object source, Class<T> clazz, Boolean whetherAssignNull) {
T target;
if (source == null) {
return null;
}
try {
target = clazz.newInstance();
if (whetherAssignNull) {
BeanUtils.copyProperties(source, target);
} else {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
}
return target;
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
return null;
}
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/14 17:24
*/
public static void clone(Object source, Object target) {
clone(source, target, true);
}
/**
*
* @date 2022/7/18 16:39
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @param whetherAssignNull 是否赋值空值:true是 false否
*/
public static void clone(Object source, Object target, Boolean whetherAssignNull) {
if (source == null) {
return;
}
try {
if (whetherAssignNull) {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
} else {
BeanUtils.copyProperties(source, target);
}
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
}
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/15 9:11
*/
public static void cglibBeanCopierCloneObject(Object source, Object target) {
BeanCopierUtils.copyProperties(source, target);
}
/**
* 对象与对象之间的数据转换
*
* @param source 转换的数据对象
* @param target 需要转换数据的对象
* @date 2022/7/15 9:11
*/
public static <T> T cglibBeanCopierCloneObject(Object source, Class<T> target) {
T t;
try {
t = target.newInstance();
BeanCopierUtils.copyProperties(source, t);
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return t;
}
/**
* 将list集合转换为传入的对象的数据集合
*
* @param sourceList 原数据集合
* @param clazz 需要转换的集合数据对象
* @return java.util.List<T>
* @date 2022/4/6 13:49
*/
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz) {
return cloneList(sourceList, clazz, true);
}
/**
*
* @date 2022/7/18 16:41
* @param sourceList 原数据集合
* @param clazz 需要转换的集合数据对象
* @param whetherAssignNull 是否赋值空值:true是 false否
* @return java.util.List<T>
*/
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz, Boolean whetherAssignNull) {
try {
List<T> targetList = new ArrayList<>(sourceList.size());
for (Object source : sourceList) {
if (whetherAssignNull) {
targetList.add(clone(source, clazz));
} else {
targetList.add(clone(source, clazz, false));
}
}
return targetList;
} catch (Exception e) {
LOGGER.error("数据转换异常", e);
return null;
}
}
/**
* 获取需要忽略的属性
*/
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<>();
for (PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
// 此处判断可根据需求修改
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
}
6、雪花算法生成ID
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @Description 雪花算法-ID
*/
@Component
public class SnowFlakeUtil {
private Logger log = LoggerFactory.getLogger(SnowFlakeUtil.class);
/**
* 记录上一毫秒数
*/
private static long lastTimestamp = -1L;
/**
* 记录毫秒内的序列,0-4095
*/
private static long sequence = 0L;
private static Long machineId = 1L;
private static Long datacenterId =1L;
public static synchronized String getId() {
long timestamp = System.currentTimeMillis();
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟被修改过,回退在上一次ID生成时间之前应当抛出异常!!!
if (timestamp < lastTimestamp) {
throw new IllegalStateException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
//如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & UniqueIdMetaData.SEQUENCE_MASK;
//毫秒内序列溢出
if (sequence == 0) {
//阻塞到下一个毫秒,获得新的时间戳
timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return String.valueOf(timestamp);
}
}
//时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
// 上次生成ID的时间截
lastTimestamp = timestamp;
// 移位并通过或运算组成64位ID
return String.valueOf(((timestamp - UniqueIdMetaData.START_TIME) << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS)
| (datacenterId << UniqueIdMetaData.DATACENTER_SHIFT_BITS)
| (machineId<< UniqueIdMetaData.MACHINE_SHIFT_BITS)
| sequence);
}
public static synchronized Long getLongId() {
return Long.parseLong(getId());
}
public UniqueId explainId(long id) {
UniqueId uniqueId = SnowFlakeUtil.convert(id);
if (uniqueId == null) {
log.error("==> 解析ID失败, ID不合法");
return null;
}
return uniqueId;
}
public Date transTime(long time) {
return new Date(time + UniqueIdMetaData.START_TIME);
}
/**
* 唯一ID对象解析返回ID
*
* @param uniqueId
* @return
*/
public static long convert(UniqueId uniqueId) {
long result = 0;
try {
result = 0L;
result |= uniqueId.getSequence();
result |= uniqueId.getMachineId() << UniqueIdMetaData.MACHINE_SHIFT_BITS;
result |= uniqueId.getDatacenterId() << UniqueIdMetaData.DATACENTER_SHIFT_BITS;
result |= uniqueId.getTimestamp() << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS;
} catch (Exception e) {
e.printStackTrace();
return result;
}
return result;
}
public static UniqueId convert(long id) {
UniqueId uniqueId = null;
try {
uniqueId = new UniqueId();
uniqueId.setSequence(id & UniqueIdMetaData.SEQUENCE_MASK);
uniqueId.setMachineId((id >>> UniqueIdMetaData.MACHINE_SHIFT_BITS) & UniqueIdMetaData.MACHINE_MASK);
uniqueId.setDatacenterId((id >>> UniqueIdMetaData.DATACENTER_SHIFT_BITS) & UniqueIdMetaData.DATACENTER_MASK);
uniqueId.setTimestamp((id >>> UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) & UniqueIdMetaData.TIMESTAMP_MASK);
} catch (Exception e) {
e.printStackTrace();
return uniqueId;
}
return uniqueId;
}
}
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UniqueId implements Serializable {
/**
* 0 + 41 + 5 + 5 + 12
* 固定 + 时间戳 + 工作机器ID + 数据中心ID + 序列号
*/
private static final long serialVersionUID = 8632670752020316524L;
/**
* 工作机器ID、数据中心ID、序列号、上次生成ID的时间戳
*/
@ApiModelProperty(value = "机器ID")
private long machineId;
@ApiModelProperty(value = "数据中心ID")
private long datacenterId;
@ApiModelProperty(value = "毫秒内序列")
private long sequence;
@ApiModelProperty(value = "时间戳")
private long timestamp;
@Override
public String toString() {
return "UniqueIdRespVo{" +
"服务机器ID=" + machineId +
", 数据中心ID=" + datacenterId +
", 毫秒内的序列=" + sequence +
", 生成时间与预设时间戳间隔=" + timestamp +
'}';
}
}
import io.swagger.annotations.ApiModelProperty;
public class UniqueIdMetaData {
/**
* 取当前系统启动时间为参考起始时间,
* 取1995-04-01为参考日
*/
public static final long START_TIME = 796665600000L;
/**
* 机器ID所占位数
*/
@ApiModelProperty(value = "机器位数")
public static final long MACHINE_ID_BITS = 5L;
/**
* 机器ID最大值31,0-31
*/
@ApiModelProperty(value = "机器ID最大")
public static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
/**
* 数据中心ID所占位数
*/
@ApiModelProperty(value = "数据中心ID所占位数")
public static final long DATACENTER_ID_BITS = 5L;
/**
* 数据中心ID最大值31,0-31
*/
@ApiModelProperty(value = "数据中心ID最大值")
public static final long MAX_DATACENTER_ID = ~(-1L << MACHINE_ID_BITS);
/**
* Sequence所占位数
*/
@ApiModelProperty(value = "序列所占位数")
public static final long SEQUENCE_BITS = 12L;
/**
* 机器ID偏移量12
*/
@ApiModelProperty(value = "机器ID偏移量")
public static final long MACHINE_SHIFT_BITS = SEQUENCE_BITS;
/**
* 数据中心ID偏移量12+5=17
*/
@ApiModelProperty(value = "数据中心ID偏移量")
public static final long DATACENTER_SHIFT_BITS = SEQUENCE_BITS + MACHINE_ID_BITS;
/**
* 时间戳的偏移量12+5+5=22
*/
@ApiModelProperty(value = "时间戳偏移量")
public static final long TIMESTAMP_LEFT_SHIFT_BITS = SEQUENCE_BITS + MACHINE_ID_BITS + DATACENTER_ID_BITS;
/**
* Sequence掩码4095
*/
@ApiModelProperty(value = "序列掩码")
public static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
/**
* 机器ID掩码1023
*/
@ApiModelProperty(value = "机器ID掩码")
public static final long MACHINE_MASK = ~(-1L << MACHINE_ID_BITS);
/**
* 数据中心掩码1023
*/
@ApiModelProperty(value = "数据中心掩码")
public static final long DATACENTER_MASK = ~(-1L << MACHINE_ID_BITS);
/**
* 时间戳掩码2的41次方减1
*/
@ApiModelProperty(value = "时间戳掩码")
public static final long TIMESTAMP_MASK = ~(-1L << 41L);
}
7、生成UUID
import java.util.UUID;
/**
* <p>DESC: UUID工具</p>
* <p>VERSION:1.0.0</p>
*/
public class UUIDUtil {
public static String get32Uuid() {
return UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
}
}
8、去掉图片的base64的头部
/**
* 去掉图片的base64的头部
*
* @param base64
* @return
*/
public static String baseurlPhotos(String base64) {
return base64.substring(base64.indexOf(",") + 1);
}
9、日期相关
import lombok.SneakyThrows;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
/**
* @Author: songmingsong
* @CreateTime: 2024-12-13
* @Description: 日期工具
* @Version: 1.0
*/
public class DateUtils {
/**
* 时间格式(yyyy-MM-dd)
*/
public final static String DATE_PATTERN = "yyyy-MM-dd";
/**
* 时间格式(yyyy-MM-dd HH:mm:ss)
*/
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* 获取当前日期 before 天的时间点
*
* @param before 往前推多少天
* @param hour 时
* @param minute 分
* @param second 秒
* @return 当前日期前推before天的 时分秒时间
*/
public static Date getTimePoint(int before, int hour, int minute, int second) {
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - before, hour, minute, second);
return calendar.getTime();
}
/**
* 日期格式化 日期格式为:yyyy-MM-dd
* @param date 日期
* @return 返回yyyy-MM-dd格式日期
*/
public static String formatDate(Date date) {
return formatDate(date, DATE_PATTERN);
}
/**
* 日期格式化 自定义格式
* @param date 日期
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
* @return 返回yyyy-MM-dd格式日期
*/
public static String formatDate(Date date, String pattern) {
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
/**
* 日期解析 日期格式为:yyyy-MM-dd HH:mm:ss
* @param dataStr 日期字符串
* @return 返回yyyy-MM-dd HH:mm:ss格式日期
*/
public static Date parse(String dataStr) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_PATTERN);
return sdf.parse(dataStr);
}
/**
* 日期解析 自定义格式
* @param date 日期字符串
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
* @return 返回Date
*/
public static Date parse(String date, String pattern) {
try {
return new SimpleDateFormat(pattern).parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 返回0时0分0秒的date
*
* @param date 日期
* @return
*/
@SneakyThrows
public static Date startOfDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
// 将时间部分设置为00:00:00.000
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
/**
* 这个月的第一天
* @param date 日期
* @return
*/
public static Date startOfMonth(Date date) {
Date date1 = startOfDay(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date1);
cal.set(Calendar.DAY_OF_MONTH,1);
return cal.getTime();
}
/**
* 获取某个月有多少天
*
* @param yearMonth
* @return
*/
public static String getLastDayOfMonth(String yearMonth) {
int year = Integer.parseInt(yearMonth.split("-")[0]); //年
int month = Integer.parseInt(yearMonth.split("-")[1]); //月
Calendar cal = Calendar.getInstance();
// 设置年份
cal.set(Calendar.YEAR, year);
// 设置月份
// cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.MONTH, month); //设置当前月的上一个月
// 获取某月最大天数
//int lastDay = cal.getActualMaximum(Calendar.DATE);
int lastDay = cal.getMinimum(Calendar.DATE); //获取月份中的最小值,即第一天
// 设置日历中月份的最大天数
//cal.set(Calendar.DAY_OF_MONTH, lastDay);
cal.set(Calendar.DAY_OF_MONTH, lastDay - 1); //上月的第一天减去1就是当月的最后一天
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("dd");
return sdf.format(cal.getTime());
}
/**
* 获得某月最大时间
* @param date
* @return
*/
public static Date getEndMonthOfDay(Date date) {
if (date == null) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime endOfDay = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
return getEndOfDay(localDateTimeToDate(endOfDay));
}
/**
* 获得某天最大时间
* @param date
* @return
*/
public static Date getStartMonthOfDay(Date date) {
if (date == null) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime endOfDay = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
return getStartOfDay(localDateTimeToDate(endOfDay));
}
public static Date getMonthLastDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 0);
calendar.add(Calendar.MONTH, 1);
return calendar.getTime();
}
/**
* 判断当天和传入的时间是否是同一天
*
* @param thatDay 另一个日期
* @return
*/
public static boolean isSameDay(Date thatDay) {
return isSameDay(thatDay, new Date());
}
/**
* 判断两个日期是否为同一天
*
* @param date1 一个日期
* @param date2 另一个日期
* @return
*/
public static boolean isSameDay(Date date1, Date date2) {
if (date1 == null || date2 == null) {
return false;
}
Calendar thisDat = Calendar.getInstance();
thisDat.setTime(date1);
Calendar thatDay = Calendar.getInstance();
thatDay.setTime(date2);
return (
thatDay.get(Calendar.YEAR) == thisDat.get(Calendar.YEAR) &&
thatDay.get(Calendar.MONTH) == thisDat.get(Calendar.MONTH) &&
thatDay.get(Calendar.DAY_OF_MONTH) == thisDat.get(Calendar.DAY_OF_MONTH)
);
}
/**
* 判断两个日期相差多少天
*
* @param endTime
* @param startTime
* @return
*/
public static int dateMinus(Date endTime, Date startTime) {
return (int) ((endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60 * 24));
}
/**
* 时间戳转字符串
*
* @param timeStamp
* @return
*/
//传入时间戳即可
public static String conversionTime(String timeStamp) {
//yyyy-MM-dd HH:mm:ss 转换的时间格式 可以自定义
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//转换
String time = sdf.format(new Date(Long.parseLong(timeStamp)));
return time;
}
/**
* 判断两个日期相差多少秒
*
* @param endTime
* @param startTime
* @return
*/
public static int dateSeconds(Date endTime, Date startTime) {
return (int) ((endTime.getTime() - startTime.getTime()) / (1000));
}
/**
* 获得某天最小时间
* @param date
* @return
*/
public static Date getStartOfDay(Date date) {
if (date == null) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
return localDateTimeToDate(startOfDay);
}
/**
* 获得某天最大时间
* @param date
* @return
*/
public static Date getEndOfDay(Date date) {
if (date == null) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
return localDateTimeToDate(endOfDay);
}
/**
* localDateTime 转date
* @param localDateTime
* @return
*/
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* 将秒转为时分秒格式【01:01:01】
* @param second 需要转化的秒数
* @return
*/
public static String secondConvertHourMinSecond(Long second) {
String str = "00:00:00";
if (second == null || second < 0) {
return str;
}
// 得到小时
long h = second / 3600;
str = h > 0 ? ((h < 10 ? ("0" + h) : h) + ":") : "00:";
// 得到分钟
long m = (second % 3600) / 60;
str += (m < 10 ? ("0" + m) : m) + ":";
//得到剩余秒
long s = second % 60;
str += (s < 10 ? ("0" + s) : s);
return str;
}
/**
*
* @param date
* @return
*/
public static String getWeekOfDate(Date date) {
String[] weekDays = {"7", "1", "2", "3", "4", "5", "6"}; // "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 将星期日转换为7
return weekDays[w]; // 直接返回对应的星期数
}
/**
* 获取两个日期之间的所有年
* @param startDate
* @param endDate
* @return
*/
public static List<String> getAllYearsBetweenDates(Date startDate, Date endDate) {
List<String> years = new ArrayList<>();
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
int startYear = startCal.get(Calendar.YEAR);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);
int endYear = endCal.get(Calendar.YEAR);
for (int year = startYear; year <= endYear; year++) {
years.add(String.valueOf(year));
}
return years;
}
/**
* 获取两个日期之间的所有月份
* @param startDate
* @param endDate
* @return
*/
public static List<String> getAllMonthsBetweenDates(Date startDate, Date endDate) {
List<String> months = new ArrayList<>();
//具体逻辑
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
startCal.set(Calendar.DAY_OF_MONTH, 1); // 设置为每个月的第一天
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);
endCal.set(Calendar.DAY_OF_MONTH, 1); // 设置为每个月的第一天
while (startCal.before(endCal) || startCal.equals(endCal)) {
int year = startCal.get(Calendar.YEAR);
int month = startCal.get(Calendar.MONTH) + 1; // Calendar中月份从0开始,所以要加1
months.add(String.format("%d-%02d", year, month)); // 格式化年份和月份为 yyyy-MM
startCal.add(Calendar.MONTH, 1); // 增加一个月
}
return months;
}
/**
* 获取两个日期间所有的日期
* @param startDate
* @param endDate
* @return
*/
public static List<String> getAllDaysBetweenDates(Date startDate, Date endDate){
List<String> days = new ArrayList<>();
//具体实现
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
while (startCal.before(endCal) || startCal.equals(endCal)) {
days.add(sdf.format(startCal.getTime()));
startCal.add(Calendar.DATE, 1);
}
return days;
}
/**
* 获取两个时间点之间的所有的整点时间
* @param startDate
* @param endDate
* @return
*/
public static List<String> getAllTimesBetweenDates(Date startDate, Date endDate,String format){
// 创建一个字符串列表用来存放整点时间
List<String> timesList = new ArrayList<>();
// 使用日历类来处理时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
// 格式化时间为 "yyyy-MM-dd HH:mm"
SimpleDateFormat sdf = new SimpleDateFormat(format);
// 逐小时遍历
// while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
while (calendar.getTime().before(endDate)) {
// 将当前时间格式化为字符串并加入列表
timesList.add(sdf.format(calendar.getTime()));
// 增加一个小时
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
return timesList;
}
/**
* 获取24小时制的时间
* @return
*/
public static List<String> getAllTimesBetweenDates(){
// 创建一个字符串数组,容量为24
String[] times24 = new String[24];
// 设置格式化器为24小时制
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("HH");
// 获取0点到23点的每一个小时
for (int i = 0; i < 24; i++) {
LocalTime time = LocalTime.of(i, 0);
times24[i] = time.format(formatter);
}
return new ArrayList<>(Arrays.asList(times24));
}
/**
* 在指定日期上增加i年,负数为减少i年
* @param date 指定的日期
* @param i 增加/减少的年数
* @return
*/
public static Date addDateYears(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.YEAR, i);
return calendar.getTime();
}
/**
* 在指定日期上增加i月,负数为减少i月
* @param date
* @param i
* @return
*/
public static Date addDateMonths(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, i);
return calendar.getTime();
}
/**
* 在指定日期上增加i周,负数为减少i周
* @param date
* @param i
* @return
*/
public static Date addDateWeeks(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.WEEK_OF_YEAR, i);
return calendar.getTime();
}
/**
* 在指定日期上增加i天,负数为减少i天
* @param date
* @param i
* @return
*/
public static Date addDateDays(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_YEAR, i);
return calendar.getTime();
}
/**
* 在指定日期上增加i分钟,负数为减少i分钟
* @param date
* @param i
* @return
*/
public static Date addDateMinute(Date date, int i) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MINUTE, i);
return calendar.getTime();
}
/**
* 在指定日期上增加i单位的时间,负数为减少i单位的时间
* @param date 指定日期
* @param i 增加/减少的时间数量
* @param unit 时间单位,如Calendar.DAY_OF_YEAR、Calendar.HOUR_OF_DAY等
* @return
*/
public static Date addDateUnits(Date date, int i,int unit) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(unit, i);
return calendar.getTime();
}
}