package com.isoftstone.common.utils;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang3.StringEscapeUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.isoftstone.common.utils.date.DateUtil;
/**
* @author leon
* @createDate 2018年5月14日 下午3:21:06
* @version v1.0
* @classRemarks 字元工具類
*/
public class StringUtil extends org.apache.commons.lang3.StringUtils{
private static final char SEPARATOR = '_';
private static final String CHARSET_NAME = "UTF-8";
private static Logger logger = LoggerFactory.getLogger(StringUtil.class);
/**
* 對double值進行四舍五入并保留兩位小數
* @param d
* @return
*/
public static Double formatDouble(double d) {
DecimalFormat df = new DecimalFormat("#.00");
return Double.valueOf(df.format(d));
}
/**
* 根據進位類型,保留幾位小數
* @param sum 數值
* @param carryType 要保留的位數
* @return
*/
// public static Double getRoundChange(Double sum,Integer carryType){
// String str = "#";
// if(sum!=null){
// if (carryType > 0){
// str +=".";
// for (int i = 0;i < carryType; i++){
// str += "#";
// }
// }
// DecimalFormat df = new DecimalFormat(str);
// return Double.valueOf(df.format(sum));
// }
// return sum;
// }
/**
* 轉換為位元組數組
* @param str
* @return
*/
public static byte[] getBytes(String str){
if (str != null){
try {
return str.getBytes(CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return null;
}
}else{
return null;
}
}
/**
* 是否包含字元串
* @param str 驗證字元串
* @param strs 字元串組
* @return 包含傳回true
*/
public static boolean inString(String str, String... strs){
if (str != null){
for (String s : strs){
if (str.equals(trim(s))){
return true;
}
}
}
return false;
}
/**
* 轉換為位元組數組
* @param str
* @return
*/
public static String toString(byte[] bytes){
try {
return new String(bytes, CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return EMPTY;
}
}
/**
* 擷取資料編号
* @param obj 差別符
* @param i 位數
* @return
*/
public static String getCode(String obj,int i) {
/**
* 目前日期+4位随機數
* 例 : XQ 20171016 5816
*/
return obj+DateUtil.getStringToDate()+DateUtil.getRandom(i).toString();
}
//生成随機數字和字母,
public static String getStringRandom(int length) {
String val = "";
Random random = new Random();
//參數length,表示生成幾位随機數
for(int i = 0; i < length; i++) {
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
//輸出字母還是數字
if( "char".equalsIgnoreCase(charOrNum) ) {
//輸出是大寫字母還是小寫字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char)(random.nextInt(26) + temp);
} else if( "num".equalsIgnoreCase(charOrNum) ) {
val += String.valueOf(random.nextInt(10));
}
}
return val;
}
/**
* 擷取token值
* @param userName 使用者名
* @param i 位數
* @return
*/
public static String getUserToken(String userName) {
//String saltStr = UUID.randomUUID().toString();
logger.info("======"+userName+"正在使用StringUtil工具類生成token值=====");
String token=null;
try {
token=userName+StringUtil.md5s(UUID.randomUUID().toString(), userName);//"@W!rf";
logger.info("======使用者"+userName+"生成的token值為:"+token+"=====");
} catch (Exception e) {
logger.info("生成使用者token報錯,異常資訊為:"+e.getMessage());
logger.error("系統錯誤:",e);
}
return token;
}
/**
* 替換掉HTML标簽方法
*/
public static String replaceHtml(String html) {
if (isBlank(html)){
return "";
}
String regEx = "<.+?>";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(html);
String s = m.replaceAll("");
return s;
}
/**
* 替換為手機識别的HTML,去掉樣式及屬性,保留回車。
* @param html
* @return
*/
public static String replaceMobileHtml(String html){
if (html == null){
return "";
}
return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
}
/**
* 縮略字元串(不區分中英文字元)
* @param str 目标字元串
* @param length 截取長度
* @return
*/
public static String abbr(String str, int length) {
if (str == null) {
return "";
}
try {
StringBuilder sb = new StringBuilder();
int currentLength = 0;
for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
currentLength += String.valueOf(c).getBytes("GBK").length;
if (currentLength <= length - 3) {
sb.append(c);
} else {
sb.append("...");
break;
}
}
return sb.toString();
} catch (UnsupportedEncodingException e) {
logger.error("系統錯誤:",e);
}
return "";
}
public static String abbr2(String param, int length) {
if (param == null) {
return "";
}
StringBuffer result = new StringBuffer();
int n = 0;
char temp;
boolean isCode = false; // 是不是HTML代碼
boolean isHTML = false; // 是不是HTML特殊字元,如
for (int i = 0; i < param.length(); i++) {
temp = param.charAt(i);
if (temp == '<') {
isCode = true;
} else if (temp == '&') {
isHTML = true;
} else if (temp == '>' && isCode) {
n = n - 1;
isCode = false;
} else if (temp == ';' && isHTML) {
isHTML = false;
}
try {
if (!isCode && !isHTML) {
n += String.valueOf(temp).getBytes("GBK").length;
}
} catch (UnsupportedEncodingException e) {
logger.error("系統錯誤:",e);
}
if (n <= length - 3) {
result.append(temp);
} else {
result.append("...");
break;
}
}
// 取出截取字元串中的HTML标記
String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)",
"$1$2");
// 去掉不需要結素标記的HTML标記
temp_result = temp_result
.replaceAll(
"</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
"");
// 去掉成對的HTML标記
temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>",
"$2");
// 用正規表達式取出标記
Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
Matcher m = p.matcher(temp_result);
List<String> endHTML = Lists.newArrayList();
while (m.find()) {
endHTML.add(m.group(1));
}
// 補全不成對的HTML标記
for (int i = endHTML.size() - 1; i >= 0; i--) {
result.append("</");
result.append(endHTML.get(i));
result.append(">");
}
return result.toString();
}
/**
* 轉換為Double類型
*/
public static Double toDouble(Object val){
if (val == null){
return 0D;
}
try {
return Double.valueOf(trim(val.toString()));
} catch (Exception e) {
return 0D;
}
}
public static Double toDecimal(Object val){
if (val == null){
return 0D;
}
try {
DecimalFormat df= new DecimalFormat("######0.00");
return Double.valueOf(df.format(val).toString());
} catch (Exception e) {
return 0D;
}
}
/**
* 轉換為Float類型
*/
public static Float toFloat(Object val){
return toDouble(val).floatValue();
}
/**
* 轉換為Long類型
*/
public static Long toLong(Object val){
return toDouble(val).longValue();
}
/**
* 轉換為Integer類型
*/
public static Integer toInteger(Object val){
return toLong(val).intValue();
}
/**
* 駝峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCamelCase(String s) {
if (s == null) {
return null;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 駝峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCapitalizeCamelCase(String s) {
if (s == null) {
return null;
}
s = toCamelCase(s);
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
/**
* 駝峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toUnderScoreCase(String s) {
if (s == null) {
return null;
}
StringBuilder sb = new StringBuilder();
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean nextUpperCase = true;
if (i < (s.length() - 1)) {
nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
}
if ((i > 0) && Character.isUpperCase(c)) {
if (!upperCase || !nextUpperCase) {
sb.append(SEPARATOR);
}
upperCase = true;
} else {
upperCase = false;
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 如果不為空,則設定值
* @param target
* @param source
*/
/*public static void setValueIfNotBlank(String target, String source) {
if (isNotBlank(source)){
target = source;
}
}*/
/**
* 轉換為JS擷取對象值,生成三目運算傳回結果
* @param objectString 對象串
* 例如:row.user.id
* 傳回:!row?'':!row.user?'':!row.user.id?'':row.user.id
*/
public static String jsGetVal(String objectString){
StringBuilder result = new StringBuilder();
StringBuilder val = new StringBuilder();
String[] vals = split(objectString, ".");
for (int i=0; i<vals.length; i++){
val.append("." + vals[i]);
result.append("!"+(val.substring(1))+"?'':");
}
result.append(val.substring(1));
return result.toString();
}
/**
* 判斷字元串是否為空
*
* @param str
* @return
*/
public static boolean isNull(String str) {
if (str == null || str.length() == 0 || str.trim().length() == 0 || str.toUpperCase().equals("NULL") ) {
return true;
} else {
return false;
}
}
/**
* 判斷字元串是否不為空
*
* @param str
* @return
*/
public static boolean isNotNull(String str) {
if (str == null || str.length() == 0 || str.trim().length() == 0 || str.toUpperCase().equals("NULL") ) {
return false;
} else {
return true;
}
}
/**
* 獲得時間戳
*
* @param format
* 時間格式
* @param count
* 附帶的随機數個數
* @return
*/
public static String getTimeMillis(String format, int count) {
try {
DateFormat dateFormat = new SimpleDateFormat(format);
String str = dateFormat.format(new Date());
Random ran = new Random();
for (int i = 0; i < count; i++) {
str = str + ran.nextInt(10);
}
return str;
} catch (Exception e) {
logger.error("系統錯誤:",e);
}
return "";
}
/**
* @param obj校驗位
* @param plainText
* 原字元串
* @return
* @throws Exception
*
* 加密算法
*/
public static String md5s(String plainText, String obj) throws Exception {
try {
if (!isNull(plainText)) {
MessageDigest md = MessageDigest.getInstance("MD5");
if (!isNull(obj)) {
md.update((plainText + obj).getBytes("utf-8"));
} else {
md.update((plainText).getBytes("utf-8"));
}
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
return buf.toString();
} else {
return null;
}
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
}
/**
* @param obj校驗位
* @param plainText
* 原字元串
* @return
* @throws Exception
*
* 加密算法
*/
public static String SHA(String plainText, Object obj) throws Exception {
try {
if (!isNull(plainText)) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update((plainText + "" + obj).getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
return buf.toString();
} else {
return null;
}
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
}
/**
* 擷取指定長度的随機密碼
* @param pwd_len
* @return
*/
public static String genRandomPassword(int pwd_len){
int i; //生成的随機數
int count = 0; //生成的密碼的長度
char[] str = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
StringBuffer pwd = new StringBuffer("");
Random r = new Random();
while(count < pwd_len){
//生成随機數,取絕對值,防止生成負數,
i = Math.abs(r.nextInt(str.length-1)); //生成的數最大為36-1
if (i >= 0 && i < str.length) {
pwd.append(str[i]);
count ++;
}
}
return pwd.toString();
}
/**
* 剪切前三級部門
* @param paths 部門路徑
* @param map Map<String, Object>map
* @return 傳回添加了剪切的部門路徑,再傳回原map
*/
public static Map<String, Object> subDeptPath(String paths,Map<String, Object> map){
if(paths.indexOf(">")>=0){
String[] depts = paths.split(">");
map.put("dept_1", StringUtil.isNull(depts[0])?"":depts[0]);
map.put("dept_2", StringUtil.isNull(depts[1])?"":depts[1]);
if(depts.length>2){ map.put("dept_3", StringUtil.isNull(depts[2])?"":depts[2]);
}else{ map.put("dept_3", ""); }
}else{
map.put("dept_1", paths);
map.put("dept_2", "");
map.put("dept_3", "");
}
return map;
}
/**
* 将strList字元資料轉換成list
* @param strList
* @param listInt
* @return
*/
public static List<Long> parseLongList(String strList,List<Long> listInt){
List<String> listStr = Arrays.asList(strList.split(","));
listInt =new ArrayList<Long>(listStr.size());
CollectionUtils.collect(listStr,
new Transformer(){
public java.lang.Object transform(java.lang.Object input){
return Long.parseLong((String)input);
}
} ,listInt );
return listInt;
}
/**
* 阿拉伯數字 轉 中文數字
* @param string
* @return
*/
public static String int2ChineseNumber(String string) {
if(isBlank(string))
return string;
String[] s1 = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
String[] s2 = { "十", "百", "千", "萬", "十", "百", "千", "億", "十", "百", "千" };
String result = "";
int n = string.length();
for (int i = 0; i < n; i++) {
int num = string.charAt(i) - '0';
if (i != n - 1 && num != 0) {
result += s1[num] + s2[n - 2 - i];
} else {
result += s1[num];
}
}
return result;
}
/**
* 中文數字 轉 阿拉伯數字
* @param chineseNumber
* @return
*/
public static int chineseNumber2Int(String chineseNumber){
int result = 0;
int temp = 1;//存放一個機關的數字如:十萬
int count = 0;//判斷是否有chArr
char[] cnArr = new char[]{'一','二','三','四','五','六','七','八','九'};
char[] chArr = new char[]{'十','百','千','萬','億'};
for (int i = 0; i < chineseNumber.length(); i++) {
boolean b = true;//判斷是否是chArr
char c = chineseNumber.charAt(i);
for (int j = 0; j < cnArr.length; j++) {//非機關,即數字
if (c == cnArr[j]) {
if(0 != count){//添加下一個機關之前,先把上一個機關值添加到結果中
result += temp;
temp = 1;
count = 0;
}
// 下标+1,就是對應的值
temp = j + 1;
b = false;
break;
}
}
if(b){//機關{'十','百','千','萬','億'}
for (int j = 0; j < chArr.length; j++) {
if (c == chArr[j]) {
switch (j) {
case 0:
temp *= 10;
break;
case 1:
temp *= 100;
break;
case 2:
temp *= 1000;
break;
case 3:
temp *= 10000;
break;
case 4:
temp *= 100000000;
break;
default:
break;
}
count++;
}
}
}
if (i == chineseNumber.length() - 1) {//周遊到最後一個字元
result += temp;
}
}
return result;
}
/**
* 金額四舍五入格式
* @param carryType 保留多少位小數
* @param amount
* @return
*/
public static String getRound(int carryType,Double amount){
String str ="#";
if(carryType>0){
str +=".";
for(int i=0;i<carryType;i++){
str+="#";
}
}
DecimalFormat df = new DecimalFormat(str);
df.setRoundingMode(RoundingMode.HALF_UP);
//amount必須.toString(),不然會有精度确實問題
String val = df.format(new BigDecimal(amount.toString()));
if(val.contains(".")){
String[] arr = val.split("\\.");
if(arr[1].length()<carryType){
int length = carryType-arr[1].length();
for(int i=0;i<length;i++){
arr[1]+="0";
}
}
return arr[0]+"."+arr[1];
}else{
if(carryType>0)
val+=".";
for(int i=0;i<carryType;i++){
val+="0";
}
return val;
}
}
/**
* 對象轉map
* @param obj
* @return
*/
public static Map<?, ?> objectToMap(Object obj) {
if(obj == null)
return null;
return new org.apache.commons.beanutils.BeanMap(obj);
}
/**
* map轉指定對象
* @param map
* @param beanClass
* @return
* @throws Exception
*/
public static Object mapToObject(Map<String, Object> map, Class<?> beanClass){
if (map == null)
return null;
Object obj = null;
try {
obj = beanClass.newInstance();
org.apache.commons.beanutils.BeanUtils.populate(obj, map);
} catch (Exception e) {
logger.error("map轉指定對象 - 異常",e);
}
return obj;
}
public static Map<String,Object> Obj2Map(Object obj) throws Exception{
Map<String,Object> map=new HashMap<String, Object>();
Field[] fields = obj.getClass().getDeclaredFields();
Field[] fields1 = obj.getClass().getFields();
for(Field field:fields){
field.setAccessible(true);
map.put(field.getName(), field.get(obj));
}
return map;
}
public static void main(String[] args) {
//System.out.println("需求編号:"+StringUtil.getCode("XQ",4));
// System.out.println(Double.parseDouble(new BigDecimal(8.123E8).toString()));
//String token=getUserToken("LG");
//System.out.println("long值:"+toLong(5));
System.out.println(getRound(2, 9000.1d));
}
}