Java开发常用Util工具类-StringUtil、CastUtil、CollectionUtil、ArrayUtil、PropsUtil
字符串工具类
StringUtil.java
package com.***.util; /** * StringUtil * @description: 字符串工具类 **/ public class StringUtil { /** * 判断是否为空字符串最优代码 * @param str * @return 如果为空,则返回true */ public static boolean isEmpty(String str){ return str == null || str.trim().length() == 0; } /** * 判断字符串是否非空 * @param str 如果不为空,则返回true * @return */ public static boolean isNotEmpty(String str){ return !isEmpty(str); } /** * 生成工单编码 * @param prefix 单据前缀 * @param suffix 工单后缀 * return 生成时间戳的工单编码 * prefix yyyyMMddHHmmssSSS 随机六位数 suffix */ public static String genOrderNo(String prefix, String suffix) { if(prefix==null){ prefix = ""; } if(suffix==null){ suffix = ""; } StringBuilder orderNo = new StringBuilder(); // 时间部分到毫秒 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String timeString = dateFormat.format(new Date()); Random rand = new Random(); // 随机数部分1/900,随机两次1/810000,在同一毫秒内,千分之一概率一样 Integer randomString = rand.nextInt(900) + 100; Integer randomString2 = rand.nextInt(900) + 100; orderNo.append(prefix); orderNo.append(timeString); orderNo.append(randomString); orderNo.append(randomString2); orderNo.append(suffix); return orderNo.toString(); } }
数据类型转换类
CastUtil.java
package com.***.util; /** * CastUtil * @description: 数据转型工具类 **/ public class CastUtil { /** * @Description: 转为String类型 * @Param: [obj] * @return: java.lang.String 如果参数为null则转为空字符串 */ public static String castString(Object obj){ return CastUtil.castString(obj,""); } /** * @Description: 转为String类型(提供默认值) * @Param: [obj, defaultValue] 将obj转为string,如果obj为null则返回default * @return: String */ public static String castString(Object obj,String defaultValue){ return obj!=null?String.valueOf(obj):defaultValue; } /** * @Description: 转为double类型,如果为null或者空字符串或者格式不对则返回0 * @Param: [obj] * @return: String */ public static double castDouble(Object obj){ return CastUtil.castDouble(obj,0); } /** * @Description: 转为double类型 ,如果obj为null或者空字符串或者格式不对则返回defaultValue * @Param: [obj, defaultValue] * @return: String obj为null或者空字符串或者格式不对返回defaultValue */ public static double castDouble(Object obj,double defaultValue){ double value = defaultValue; //声明结果,把默认值赋给结果 if (obj!=null){ //判断是否为null String strValue = castString(obj); //转换为String if (StringUtil.isNotEmpty(strValue)){ //判断字符串是否为空(是否为空只能判断字符串,不能判断Object) try{ value = Double.parseDouble(strValue); //不为空则把值赋给value }catch (NumberFormatException e){ value = defaultValue; //格式不对把默认值赋给value } } } return value; } /** * 转为long型,如果obj为null或者空字符串或者格式不对则返回0 * @param obj * @return */ public static long castLong(Object obj){ return CastUtil.castLong(obj,0); } /** * 转为long型(提供默认数值),如果obj为null或者空字符串或者格式不对则返回defaultValue * @param obj * @param defaultValue * @return obj为null或者空字符串或者格式不对返回defaultValue */ public static long castLong(Object obj,long defaultValue){ long value = defaultValue; //声明结果,把默认值赋给结果 if (obj!=null){ //判断是否为null String strValue = castString(obj); //转换为String if (StringUtil.isNotEmpty(strValue)){ //判断字符串是否为空(是否为空只能判断字符串,不能判断Object) try{ value = Long.parseLong(strValue); //不为空则把值赋给value }catch (NumberFormatException e){ value = defaultValue; //格式不对把默认值赋给value } } } return value; } /** * 转为int型 * @param obj * @return 如果obj为null或者空字符串或者格式不对则返回0 */ public static int castInt(Object obj){ return CastUtil.castInt(obj,0); } /** * 转为int型(提供默认值) * @param obj * @param defaultValue * @return 如果obj为null或者空字符串或者格式不对则返回defaultValue */ public static int castInt(Object obj,int defaultValue){ int value = defaultValue; //声明结果,把默认值赋给结果 if (obj!=null){ //判断是否为null String strValue = castString(obj); //转换为String if (StringUtil.isNotEmpty(strValue)){ //判断字符串是否为空(是否为空只能判断字符串,不能判断Object) try{ value = Integer.parseInt(strValue); //不为空则把值赋给value }catch (NumberFormatException e){ value = defaultValue; //格式不对把默认值赋给value } } } return value; } /** * 转为boolean型,不是true的返回为false * @param obj * @return */ public static boolean castBoolean(Object obj){ return CastUtil.castBoolean(obj,false); } /** * 转为boolean型(提供默认值) * @param obj * @param defaultValue * @return */ public static boolean castBoolean(Object obj,boolean defaultValue){ boolean value = defaultValue; if (obj!=null){ //为null则返回默认值 value = Boolean.parseBoolean(castString(obj)); //底层会把字符串和true对比,所以不用判断是否为空字符串 } return value; } }
集合工具类
CollectionUtil.java
package com.***.util; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import java.util.Collection; import java.util.Map; /** * CollectionUtil * @description: 集合工具类 **/ public class CollectionUtil { /** * 判断collection是否为空 * @param collection * @return */ public static boolean isEmpty(Collection<?> collection){ //return CollectionUtils.isEmpty(collection); return collection == null || collection.isEmpty(); } /** * 判断Collection是否非空 * @return */ public static boolean isNotEmpty(Collection<?> collection){ return !isEmpty(collection); } /** * 判断map是否为空 * @param map * @return */ public static boolean isEmpty(Map<?,?> map){ //return MapUtils.isEmpty(map); return map == null || map.isEmpty(); } /** * 判断map是否非 * @param map * @return */ public static boolean isNotEmpty(Map<?,?> map){ return !isEmpty(map); } }
数组工具类
ArrayUtil.java
/** * 数组工具类 */ public class ArrayUtil { /** * 判断数组是否为空 * @param array * @return */ public static boolean isNotEmpty(Object[] array){ return !isEmpty(array); } /** * 判断数组是否非空 * @param array * @return */ public static boolean isEmpty(Object[] array){ return array==null||array.length==0; } }
差集工具类
/** * 获取差集 * @param newStrs 新集合: ,分割的字符串, * 例如: 1,2,3 * @param oldStrs 旧集合: ,分割的字符串, * 例如: a,2 * @param differenceSet_new 需要新增的差集:new - old * 例如: [a] * @param differenceSet_old 需要删除的差集:old - new * 例如: [1, 3] */ public static void getDifferenceSet(String newStrs, String oldStrs, List differenceSet_new, List differenceSet_old){ //多数据替换 - 删除&新增,即在新的也在旧的中的不变 //oldStrs = "1,2,3"; //newStrs = "a,2"; //differenceSet_new = new ArrayList(); //新的部分new - old //differenceSet_old = new ArrayList(); //旧的部分old - new String[] oldArr = StringUtil.isEmpty(oldStrs) ? new String[0] : oldStrs.split(","); String[] newArr = StringUtil.isEmpty(newStrs) ? new String[0] : newStrs.split(","); for (String old:oldArr){ //遍历旧元素 if (!Arrays.asList(newArr).contains(old)){ //判断旧元素是否在新集合里面 differenceSet_old.add(old); System.out.println("删除旧元素:"+old); } } for (String n:newArr){ //遍历新元素 if (!Arrays.asList(oldArr).contains(n)){ //判断新元素是否在旧集合里面 differenceSet_new.add(n); System.out.println("新增新元素:"+n); } } }
调用
String oldStrs = "1,2,3"; String newStrs = "a,2"; List result_add = new ArrayList(); //新的部分new - old List result_del = new ArrayList(); //旧的部分old - new getDifferenceSet(newStrs,oldStrs,result_add,result_del); System.out.println(result_add.toString()); System.out.println(result_del.toString());
Properties文件操作类
PropsUtil.java
package com.***.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 属性文件工具类 */ public class PropsUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class); /** * 加载属性文件 * @param fileName fileName一定要在class下面及java根目录或者resource跟目录下 * @return */ public static Properties loadProps(String fileName){ Properties props = new Properties(); InputStream is = null; try { //将资源文件加载为流 is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
props.load(is); if(is==null){ throw new FileNotFoundException(fileName+"file is not Found"); } } catch (FileNotFoundException e) { LOGGER.error("load properties file filure",e); }finally { if(is !=null){ try { is.close(); } catch (IOException e) { LOGGER.error("close input stream failure",e); } } } return props; } /** * 获取字符型属性(默认值为空字符串) * @param props * @param key * @return */ public static String getString(Properties props,String key){ return getString(props,key,""); } /** * 获取字符型属性(可制定默认值) * @param props * @param key * @param defaultValue 当文件中无此key对应的则返回defaultValue * @return */ public static String getString(Properties props,String key,String defaultValue){ String value = defaultValue; if (props.containsKey(key)){ value = props.getProperty(key); } return value; } /** * 获取数值型属性(默认值为0) * @param props * @param key * @return */ public static int getInt(Properties props,String key){ return getInt(props,key,0); } /** * 获取数值型属性(可指定默认值) * @param props * @param key * @param defaultValue * @return */ public static int getInt(Properties props,String key,int defaultValue){ int value = defaultValue; if (props.containsKey(key)){ value = CastUtil.castInt(props.getProperty(key)); } return value; } /** * 获取布尔型属性(默认值为false) * @param props * @param key * @return */ public static boolean getBoolean(Properties props,String key){ return getBoolean(props,key,false); } /** * 获取布尔型属性(可指定默认值) * @param props * @param key * @param defaultValue * @return */ public static boolean getBoolean(Properties props,String key,Boolean defaultValue){ boolean value = defaultValue; if (props.containsKey(key)){ value = CastUtil.castBoolean(props.getProperty(key)); } return value; } }
用到的maven坐标
<!--slf4j--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.9</version> </dependency>
常用流操作工具类
StreamUtil.java
public class StreamUtil { private static final Logger LOGGER = LoggerFactory.getLogger(StreamUtil.class); /** * 从输入流中获取字符串 * @param is * @return */ public static String getString(InputStream is){ StringBuilder sb = new StringBuilder(); try { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line; while((line=reader.readLine())!=null){ sb.append(line); } } catch (IOException e) { LOGGER.error("get string failure",e); throw new RuntimeException(e); } return sb.toString(); } }
编码工具类
public class CodecUtil { private static final Logger LOGGER = LoggerFactory.getLogger(CodecUtil.class); /** * 将URL编码 */ public static String encodeURL(String source){ String target; try { target = URLEncoder.encode(source,"utf-8"); } catch (UnsupportedEncodingException e) { LOGGER.error("encode url failure",e); throw new RuntimeException(e); //e.printStackTrace(); } return target; } /** * 将URL解码 */ public static String dencodeURL(String source){ String target; try { target = URLDecoder.decode(source,"utf-8"); } catch (UnsupportedEncodingException e) { LOGGER.error("encode url failure",e); throw new RuntimeException(e); //e.printStackTrace(); } return target; } }
Json工具类
package org.smart4j.framework.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; /** * @program: JsonUtil * @description: JSON工具类 * @author: Created by QiuYu * @create: 2018-10-24 15:55 */ public class JsonUtil { private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class); private static final ObjectMapper OBJECT_MAPPER =new ObjectMapper(); /** * 将POJO转换为JSON */ public static <T> String toJson(T obj){ String json; try { json = OBJECT_MAPPER.writeValueAsString(obj); } catch (JsonProcessingException e) { LOGGER.error("convert POJO to JSON failure",e); throw new RuntimeException(e); //e.printStackTrace(); } return json; } /** * 将JSON转为POJO */ public static <T> T fromJson(String json,Class<T> type){ T pojo; try { pojo = OBJECT_MAPPER.readValue(json,type); } catch (IOException e) { LOGGER.error("convert JSON to POJO failure",e); throw new RuntimeException(e); //e.printStackTrace(); } return pojo; } }
日期工具类
DataUtil.java
/** * 根据年月获取当月最后一天 * @param yearmonth yyyy-MM * @return yyyy-MM-dd * @throws ParseException */ public static String getLastDayOfMonth(String yearmonth) { try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM"); Date dd = format.parse(yearmonth); Calendar cal = Calendar.getInstance(); cal.setTime(dd); int cc=cal.getActualMaximum(Calendar.DAY_OF_MONTH); String result = yearmonth+"-"+cc; return result; } catch (ParseException e) { e.printStackTrace(); } return null; }
时间戳工具类
/** * 时间戳转换成日期格式字符串 * @param seconds 精确到秒的字符串 * @param formatStr 为null时默认yyyy-MM-dd HH:mm:ss * @return 返回日期字符串 */ public static String timeStamp2Date(String seconds,String format) { if(seconds == null || seconds.isEmpty() || seconds.equals("null")){ return ""; } if(format == null || format.isEmpty()){ format = "yyyy-MM-dd HH:mm:ss"; } SimpleDateFormat sdf = new SimpleDateFormat(format); //Date是精确到毫秒的13位时间戳,所以秒要*1000 Date date = new Date(Long.valueOf(seconds+"000")); String dateString = sdf.format(date); return dateString; } /** * 日期格式字符串转换成时间戳 * @param date 字符串日期 * @param format 默认:yyyy-MM-dd HH:mm:ss * @return 精确到秒的时间戳 */ public static String date2TimeStamp(String date_str,String format){ if(format == null || format.isEmpty()){ format = "yyyy-MM-dd HH:mm:ss"; } try { SimpleDateFormat sdf = new SimpleDateFormat(format); return String.valueOf(sdf.parse(date_str).getTime()/1000); } catch (Exception e) { e.printStackTrace(); } return ""; } /** * 取得当前时间戳(精确到秒) * @return */ public static String getNowTimeStamp(){ long time = System.currentTimeMillis(); String timestamp = String.valueOf(time/1000); return timestamp; }
精度计算工具类
DoubleTool.java
package com.gmtx.system.tools; import java.io.Serializable; import java.math.BigDecimal; import java.math.RoundingMode; /** * @ClassName: DoubleTool * @Description: java类精确计算小数 * double的计算不精确,会有类似0.0000000000000002的误差,正确的方法是使用BigDecimal或者用整型,整型地方法适合于货币精度已知的情况,比如12.11+1.10转成1211+110计算,最后再/100即可 * @author 秋雨 * 修改历史 * 序号------原因------修改人---日期--- * 1. * 2. */ public class DoubleTool implements Serializable { private static final long serialVersionUID = -3345205828566485102L; //默认除法运算精度 private static final Integer DEF_DIV_SCALE = 2; /** * 提供精确的加法运算。 * @param value1 被加数 * @param value2 加数 * @return 两个参数的和 */ public static Double add(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * @param value1 被减数 * @param value2 减数 * @return 两个参数的差 */ public static double sub(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * @param value1 被乘数 * @param value2 乘数 * @return 两个参数的积 */ public static Double mul(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。 * @param dividend 被除数 * @param divisor 除数 * @return 两个参数的商 */ public static Double divide(Double dividend, Double divisor) { return divide(dividend, divisor, DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。 * @param dividend 被除数 * @param divisor 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static Double divide(Double dividend, Double divisor, Integer scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(dividend)); BigDecimal b2 = new BigDecimal(Double.toString(divisor)); return b1.divide(b2, scale,RoundingMode.HALF_UP).doubleValue(); } /** * 提供指定数值的(精确)小数位四舍五入处理。 * @param value 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double value,int scale){ if(scale<0){ throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(value)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale, RoundingMode.HALF_UP).doubleValue(); } }
下载文件工具类
/** * 下载url的文件到指定文件路径里面,如果文件父文件夹不存在则自动创建 * url 下载的http地址 * path 文件存储地址 * return 如果文件大小大于2k则返回true */ public static boolean downloadCreateDir(String url,String path){ HttpURLConnection connection=null; InputStream in = null; FileOutputStream o=null; try{ URL httpUrl=new URL(url); connection = (HttpURLConnection) httpUrl.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("Charset", "gbk"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setRequestMethod("GET"); byte[] data=new byte[1024]; File f=new File(path); File parentDir = f.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } if(connection.getResponseCode() == 200){ in = connection.getInputStream(); o=new FileOutputStream(path); int n=0; while((n=in.read(data))>0){ o.write(data, 0, n); o.flush(); } } if(f.length()>2048){ //代表文件大小 return true; //如果文件大于2k则返回true } }catch(Exception ex){ ex.printStackTrace(); }finally{ try{ if(in != null){ in.close(); } }catch(IOException ex){ ex.printStackTrace(); } try{o.close();}catch(Exception ex){} try{connection.disconnect();}catch(Exception ex){} } return false; }
解压ZIP工具类
package com.***.tools; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * 解压zip文件 */ public final class ZipUtil { private static final int buffer = 2048; /** * 解压Zip文件 * @param path zip文件目录 */ public static void unZip(String path) { int count = -1; String savepath = ""; File file = null; InputStream is = null; FileOutputStream fos = null; BufferedOutputStream bos = null; savepath = path.substring(0, path.lastIndexOf(".")) + File.separator; // 保存解压文件目录 new File(savepath).mkdir(); // 创建保存目录 ZipFile zipFile = null; try { zipFile = new ZipFile(path,Charset.forName("GBK")); // 解决中文乱码问题 Enumeration<?> entries = zipFile.entries(); //枚举ZIP中的所有文件 while (entries.hasMoreElements()) { byte buf[] = new byte[buffer]; ZipEntry entry = (ZipEntry) entries.nextElement(); String filename = entry.getName(); //获取文件名 filename = savepath + filename; boolean ismkdir = false; if (filename.lastIndexOf("/") != -1) { // 检查此文件是否带有文件夹 ismkdir = true; } if (entry.isDirectory()) { // 如果此枚举文件是文件夹则创建,并且遍历下一个 file = new File(filename); file.mkdirs(); continue; } file = new File(filename); //此枚举文件不是目录 if (!file.exists()) { //如果文件不存在并且文件带有目录 if (ismkdir) { new File(filename.substring(0, filename .lastIndexOf("/"))).mkdirs(); // 先创建目录 } } file.createNewFile(); //再创建文件 is = zipFile.getInputStream(entry); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos, buffer); while ((count = is.read(buf)) > -1) { bos.write(buf, 0, count); } bos.flush(); } } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } if (fos != null) { fos.close(); } if (is != null) { is.close(); } if (zipFile != null) { zipFile.close(); } } catch (Exception e) { e.printStackTrace(); } } } }
文件编码转码
将GBK编码的文件转为UTF-8编码的文件
经常配合上一个使用,下载的压缩包解压为文件然后解码。
/** * 把GBK文件转为UTF-8 * 两个参数值可以为同一个路径 * @param srcFileName 源文件 * @param destFileName 目标文件 * @throws IOException */ private static void transferFile(String srcFileName, String destFileName) throws IOException { String line_separator = System.getProperty("line.separator"); FileInputStream fis = new FileInputStream(srcFileName); StringBuffer content = new StringBuffer(); DataInputStream in = new DataInputStream(fis); BufferedReader d = new BufferedReader(new InputStreamReader(in, "GBK")); //源文件的编码方式 String line = null; while ((line = d.readLine()) != null) content.append(line + line_separator); d.close(); in.close(); fis.close(); Writer ow = new OutputStreamWriter(new FileOutputStream(destFileName), "utf-8"); //需要转换的编码方式 ow.write(content.toString()); ow.close(); }
打印方法栈
import java.text.MessageFormat; /** * MethodStackUtil * @author: 秋雨 * 2021-07-23 10:04 **/ public class MethodStackUtil { /** * 打印全部方法栈 * 包括 * java.lang.Thread.getStackTrace() 1,589 <- * MethodStackUtil.getStackTrace() 20 <- * @return */ public static String getStackTrace() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); if(stackTrace == null) { return "no stack..."; } StringBuffer stackTraceSB = new StringBuffer(); for(StackTraceElement stackTraceElement : stackTrace) { if(stackTraceSB.length() > 0) { stackTraceSB.append(" <- "); stackTraceSB.append(System.getProperty("line.separator")); } stackTraceSB.append(MessageFormat.format("{0}.{1}() {2}" ,stackTraceElement.getClassName() ,stackTraceElement.getMethodName() ,stackTraceElement.getLineNumber())); } return stackTraceSB.toString(); } /** * 打印方法栈 - 此方法的上层所有调用者 * 不包括ava.lang.Thread.getStackTrace()和MethodStackUtil.getStackTrace() * @return */ public static String getParentStackTrace() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); if(stackTrace == null) { return "no stack..."; } StringBuffer stackTraceSB = new StringBuffer(); String classname = Thread.currentThread().getStackTrace()[1].getClassName(); //静态方法获取类名 for(StackTraceElement stackTraceElement : stackTrace) { if ("getStackTrace".contains(stackTraceElement.getMethodName()) || classname.contains(stackTraceElement.getClassName())){ continue; } if(stackTraceSB.length() > 0) { stackTraceSB.append(" <- "); stackTraceSB.append(System.getProperty("line.separator")); } stackTraceSB.append(MessageFormat.format("{0}.{1}() {2}" ,stackTraceElement.getClassName() ,stackTraceElement.getMethodName() ,stackTraceElement.getLineNumber())); } return stackTraceSB.toString(); } /** * 打印方法栈 - 只打印指定包名或者类名的下的方法 * @param packageName 包名 - 打印指定包名下的方法栈 ,可以写包名的一部分或者类名,例如: com.bus * @return */ public static String getStackTraceByPackage(String packageName) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); if(stackTrace == null) { return "no stack..."; } StringBuffer stackTraceSB = new StringBuffer(); for(StackTraceElement stackTraceElement : stackTrace) { if (!stackTraceElement.getClassName().contains(packageName)){ //如果类全名不含packageName则不打印 continue; } if(stackTraceSB.length() > 0) { stackTraceSB.append(" <- "); stackTraceSB.append(System.getProperty("line.separator")); } stackTraceSB.append(MessageFormat.format("{0}.{1}() {2}" ,stackTraceElement.getClassName() ,stackTraceElement.getMethodName() ,stackTraceElement.getLineNumber())); } return stackTraceSB.toString(); } }
进制解析工具类
package com.autumn.util; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * 进制操作工具类(十六进制,二进制) * 用于解析设备发送的十六进制Hex数据及发送指令拼接十六进制 */ public class HexUtil { /** * 十六进制字符串转short数组 * 这里得用short存储,因为short类型取值范围为-128~127,而1字节的十六进制范围为0~255 * @param hexStr 十六进制字符串 ,例如:010A0FFE * @return short数组,例如[1, 10, 15, 254] */ public static short[] hexStrToByteArray(String hexStr) { //byte列表 List<Short> byteList = new ArrayList<>(); //计算列表长度,每两位16进制为一个元素 int len = hexStr.length() / 2; //遍历16进制字符串 for (int i = 0; i < len; i++) { //每次取两个16进制数据转换 int index = i * 2; String hexEle = hexStr.substring(index, index + 2); Short b = (short) ((Character.digit(hexEle.charAt(0), 16) << 4) + Character.digit(hexEle.charAt(1), 16)); byteList.add(b); } //直接toArray只能转换为包装类Short数组,不能转换为基本类型short数组 //Short[] byteArray = byteList.toArray(new Short[byteList.size()]); // for循环把list转为基本类型shrot数组 short[] byteArray = new short[byteList.size()]; for (int i = 0; i < byteList.size(); i++) { byteArray[i] = byteList.get(i); } return byteArray; } /** * 取数组中的一段数据,转为16进制字符串 * @param byteArray byte数组 * @param start 起始元素 * @param end 结束元素 * @return */ public static String byteArryTohexStr(short[] byteArray, int start, int end) { // 使用StringBuilder进行高效字符串连接 StringBuilder stringBuilder = new StringBuilder(); // 遍历short数组 for (int i = start; i <= end; i++) { // 将short值转换为String并添加到StringBuilder String hex = decToHex(byteArray[i]); stringBuilder.append(hex); } // 将StringBuilder转换为String String result = stringBuilder.toString(); return result; } /** * 十六进制加一 * @param hex 十六进制字符串 * @return 十六进制字符串 */ public static String HexAddOne(String hex){ //先把16进制转为十进制 int num = Integer.parseInt(hex,16); //十进制自加一 num++; //最后再把十进制转为十六进制 return Integer.toHexString(num).toUpperCase(); // 转换为大写形式 } /** * 十六进制加法 * @param hex * @param num * @return */ public static String HexAdd(String hex,int num){ //先把16进制转为十进制 int num_d = Integer.parseInt(hex,16); //十进制计算 num_d+=num; //最后再把十进制转为十六进制 return Integer.toHexString(num_d).toUpperCase(); // 转换为大写形式 } /** * 十进制转十六进制 * @param dec 十进制 (一个字节8bit位范围0~255): 例如:255 * @return string 十六进制 (一个字节8bit位范围00~FF): 例如: FF */ public static String decToHex(int dec) { //十进制转16进制,可以接收0~255之间数字(&0xFF实现,高于255则只保留低8位),但是如果小于16则只返回1位 //return Integer.toHexString(0xFF & dec); // if (dec<0 || dec>255){ // throw new RuntimeException("This decimal is greater than 255!"); // } //通过fomat实现不足两位时前面会补0 return String.format("%02X",dec); } /** * 十六进制转十进制 * @param hex 十六进制 例: FF * @return int 十进制 例: 255 */ public static int hexToDec(String hex) { return Integer.parseInt(hex, 16); } /** * 二进制转十进制 * @param bin 例: 1111 * @return 十进制 例: 15 */ public static int binToDec(String bin) { return Integer.parseInt(bin, 2); } /** * 十进制转二进制 * @param dec 十进制 例如: 254 * @return 二进制 例: 11111110 */ public static String decToBin(int dec) { String binaryString = Integer.toBinaryString(dec); binaryString = String.format("%" + 8 + "s", binaryString).replace(' ', '0'); return binaryString; } /** * 十六进制转换为二进制字符串 * 最低为1个字节长度8位,如果小于8位左侧补零,如果超过8位则显示实际位数 * @param hex 二进制字符串 * @return 二进制 */ public static String hexToBinary(String hex) { int num = Integer.parseInt(hex, 16); String binaryString = Integer.toBinaryString(num); binaryString = String.format("%" + 8 + "s", binaryString).replace(' ', '0'); return binaryString; } /** * 将二进制字符串转换回十六进制 * 最低为2位十六进制,如果不足两位则左侧补零,如果超过两位则用实际位数显示 * @param binary 二进制数据 例: 1010 * @return 返回十六进制 例: 0A * 超过2位的十六进制返回值需要调用ensureLength在前面补0 */ public static String binaryToHex(String binary) { int num = Integer.parseInt(binary, 2); String hexStr = Integer.toHexString(num).toUpperCase(); hexStr = String.format("%" + 2 + "s", hexStr).replace(' ', '0'); return hexStr; } /** * 修改二进制某位数据状态位 * @param binStr 二进制字符串 例: 0000 1000 * @param index 字符下标 例: 3 * @param flag 二进制状态位 例: 1 * @return 0001 1000 */ public static String setBinaryFlag(String binStr,int index,char flag){ StringBuilder seqBuffer = new StringBuilder(binStr); seqBuffer.setCharAt(index, flag); return seqBuffer.toString(); } /** * 确保进制字符串至少有minLength位 * @param src 进制字符串 * @param minLength 确保最低这个位数,不足左侧补0 * @return 返回 */ public static String ensureLength(String src, int minLength) { return String.format("%" + minLength + "s", src).replace(' ', '0'); } /** * 把字符扩充到指定字符串 * @param src 原字符 例: 1A * @param minlength 长度 例: 4 * @param padChar 填充字符串 例: 0 * @return 左侧填充后的字符 例: 001A */ public static String ensureLength(String src, int minlength, char padChar) { return String.format("%" + minlength + "s", src).replace(' ', padChar); } /** * 把字符串分割成指定大小的列表集合 * @param str 字符串 例: "abcdefg" * @param chunkSize 每块的字符长度 例: 2 * @return 返回的List集合 例: ["ab", "cd", "ef", "g"] */ public static List<String> strSplit(String str, int chunkSize) { return IntStream.iterate(0, i -> i + chunkSize) //从0开始索引,每次递增chunkSize .limit((int) Math.ceil((double) str.length() / chunkSize)) //限制流的大小,计算需要块的数量 .mapToObj(i -> str.substring(i, Math.min(i + chunkSize, str.length()))) //i作为参数,每次截取i到i+chunkSize或length .collect(Collectors.toList()); //最终转为list集合 } /** * 获取字符的ascii * @param ch * @return */ public static int getASCII(char ch) { return (int) ch; } /** * 验证是否为BCD码(Binary-Coded Decimal) * @param hexData 十六进制字符串 * @return */ public static boolean isValidBCD(String hexData) { short[] shorts = HexUtil.hexStrToByteArray(hexData); return isValidBCD(shorts); } /** * 验证是否为BCD码(Binary-Coded Decimal) * BCD用4位二进制表示一个十进制,所以要验证每个字节的高低四位是否都在0-9范围之内 * @param data 字节数组 * @return */ public static boolean isValidBCD(short[] data) { for (short b : data) { // 获取高四位 int high = (b >> 4) & 0x0F; // 获取低四位 int low = b & 0x0F; // 验证高四位和低四位是否都在0-9范围内 if (high > 9 || low > 9) { return false; } } return true; } /** * 浮点数转换为十六进制 * @param value 浮点数 如: 1.23f * @return 十六进制 如: 3f9d70a4 */ public static String floatToHex(float value) { //先把小数转为10进制 return Integer.toHexString(Float.floatToIntBits(value)); } /** * 浮点数转换为十六进制 * @param value 浮点数 如: 11.233d * @return 十六进制 如: 4026774bc6a7ef9e */ public static String doubleToHex(double value) { return Long.toHexString(Double.doubleToLongBits(value)); } /** * 十六进制转为浮点数 * @param hex 十六进制 如: 3f9d70a4 * @return 浮点数 如: 1.23 */ public static float hexToFloat(String hex) { return Float.intBitsToFloat(Integer.parseUnsignedInt(hex, 16)); } /** * 十六进制转为浮点数 * @param hex 十六进制 如: 4026774bc6a7ef9e * @return 浮点数 如: 11.233 */ public static double hexToDouble(String hex) { return Double.longBitsToDouble(Long.parseUnsignedLong(hex, 16)); } public static void main(String[] args) { // Long number = Long.parseUnsignedLong("FBD626CC4961A4FC", 16); // String numberToPrint = Long.toUnsignedString(number); // System.out.println(number); // System.out.println(numberToPrint); // boolean s = isValidBCD("22334455667710"); // System.out.println(s); String s = doubleToHex(11.233d); System.out.println(Double.doubleToLongBits(11.233d)); System.out.println(s); double v = hexToDouble(s); System.out.println(v); } }
地理位置工具类
package com.autumn.util; /** * 地理位置工具类 * 根据经纬度计算距离和方位角 */ public class GeoUtil { private static final double EARTH_RADIUS = 6371.0; // 地球半径,单位为千米 /** * 将角度转换为弧度 * @param degree * @return */ private static double degToRadians(double degree) { return degree * Math.PI / 180.0; } /** * 计算两个经纬度之间的距离 * 根据 Haversine 公式计算两点之间的大圆距离 * @param lon1 点1经度 * @param lat1 点1纬度 * @param lon2 点2经度 * @param lat2 点2纬度 * @return */ public static double calculateDistance(double lon1, double lat1, double lon2, double lat2) { double lat1Rad = degToRadians(lat1); double lat2Rad = degToRadians(lat2); double deltaLat = degToRadians(lat2 - lat1); double deltaLon = degToRadians(lon2 - lon1); double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return EARTH_RADIUS * c; } /** * 计算两个经纬度之间的方位角 * @param lon1 点1经度 * @param lat1 点1纬度 * @param lon2 点2经度 * @param lat2 点2纬度 * @return */ public static double calculateBearing(double lon1, double lat1, double lon2, double lat2) { double lat1Rad = degToRadians(lat1); double lat2Rad = degToRadians(lat2); double deltaLonRad = degToRadians(lon2 - lon1); double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad); double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad); double bearingRad = Math.atan2(y, x); return (Math.toDegrees(bearingRad) + 360) % 360; } public static void main(String[] args) { //百度 double lon1 = 119.245264; //点1经度 double lat1= 32.296474; //点1纬度 double lon2 = 119.401907; //点2经度 double lat2 = 32.352583; //点2纬度 /* gps lon1 = 119.23341222264028; lat1 = 32.29273260601193; lon2 = 119.39002529645323; lat2 = 32.34811684086083; */ double distance = GeoUtil.calculateDistance(lon1, lat1, lon2, lat2); double bearing = GeoUtil.calculateBearing(lon1, lat1, lon2, lat2); System.out.println("Distance: " + distance + " KM"); System.out.println("Bearing: " + bearing + " degrees"); } }
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~