Fork me on GitHub

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");
    }
}

 

posted @ 2018-08-15 21:51  秋夜雨巷  阅读(29107)  评论(1编辑  收藏  举报