BaseUtils.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. package org.springblade.common.utils;
  2. import com.alibaba.cloud.commons.lang.StringUtils;
  3. import org.checkerframework.checker.regex.RegexUtil;
  4. import org.springblade.common.constant.RegexConstant;
  5. import org.springblade.common.vo.DataVO;
  6. import java.io.*;
  7. import java.math.BigDecimal;
  8. import java.math.BigInteger;
  9. import java.math.RoundingMode;
  10. import java.security.MessageDigest;
  11. import java.time.*;
  12. import java.time.format.DateTimeFormatter;
  13. import java.util.*;
  14. import java.util.regex.Matcher;
  15. import java.util.regex.Pattern;
  16. import java.util.stream.Collectors;
  17. import java.util.stream.IntStream;
  18. import static java.math.BigDecimal.*;
  19. /**
  20. * @author yangyj
  21. * @Date 2022/7/8 11:08
  22. * @description 基础工具类
  23. */
  24. public class BaseUtils {
  25. public static DateTimeFormatter chineseDateFm = DateTimeFormatter.ofPattern("yyyy年M月d日", Locale.CHINA);
  26. public static Pattern KM = Pattern.compile(RegexConstant.KM_REG);
  27. public static double k2d(Object k) {
  28. Matcher mt = KM.matcher(k.toString());
  29. if (mt.find()) {
  30. return Double.parseDouble(mt.group(1)) * 1000 + Double.parseDouble(mt.group(2));
  31. }
  32. return -1;
  33. }
  34. public static Double milestone(String s){
  35. Pattern pattern=Pattern.compile("(?i)K(\\d+)\\+([\\d.]+)");
  36. Matcher matcher = pattern.matcher(s);
  37. if(matcher.find()){
  38. return Double.parseDouble(matcher.group(1))*1000+ Double.parseDouble(matcher.group(2));
  39. }
  40. return null;
  41. }
  42. /**
  43. * @return java.util.Map<java.lang.String, java.lang.String>
  44. * @Description 将key1(val1)key2(val2)key3(val3)...这种格式的参数转换为Map
  45. * @Param [str]
  46. * @Author yangyj
  47. * @Date 2022.08.12 10:39
  48. **/
  49. public static Map<String, String> string2Map(String str) {
  50. Map<String, String> result = new HashMap<>(15);
  51. if (StringUtils.isNotEmpty(str)) {
  52. String[] args = str.split("\\)");
  53. for (String a : args) {
  54. if (StringUtils.isNotEmpty(a)) {
  55. String[] kv = a.split("\\(");
  56. result.put(kv[0], kv[1]);
  57. }
  58. }
  59. }
  60. return result;
  61. }
  62. /**
  63. * @return java.lang.Boolean
  64. * @Description 基础数据类型批量非空判断
  65. * @Param [args]
  66. * @Author yangyj
  67. * @Date 2022.08.26 11:14
  68. **/
  69. public static Boolean isNotNull(Object... args) {
  70. if (args != null) {
  71. for (Object obj : args) {
  72. if (obj == null || "".equals(obj)) {
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. return false;
  79. }
  80. /*将不同长度的字符串转换为固定长度的Long*/
  81. public static long str2Long(String input) {
  82. try {
  83. MessageDigest md = MessageDigest.getInstance("SHA-256");
  84. byte[] hash = md.digest(input.getBytes());
  85. BigInteger bigInt = new BigInteger(1, hash);
  86. // 取正整数
  87. return bigInt.longValue() & Long.MAX_VALUE;
  88. } catch (Exception e) {
  89. throw new RuntimeException(e);
  90. }
  91. }
  92. /**最小分割片*/
  93. public static int sliceNumber(Integer len,Integer capacity){
  94. return (int)Math.ceil(len/(double)capacity);
  95. }
  96. /**
  97. * @Description 判断对象是否为数值
  98. * @Param [value]
  99. * @Author yangyj
  100. * @Date 2023.01.17 13:48
  101. **/
  102. static final String NUM_REG = "^[+-]?\\d+(\\.\\d+)?$";
  103. public static boolean isNumber(Object value) {
  104. if ((value == null) ) {
  105. return false;
  106. }
  107. String stringValue = value.toString().trim();
  108. if (stringValue.isEmpty()) {
  109. return false;
  110. }
  111. if (value instanceof Number) {
  112. return true;
  113. }
  114. return Pattern.matches(NUM_REG,stringValue);
  115. }
  116. static final String ZERO_REG = "^(0(\\.0*)?|0[eE]-\\d+)$";
  117. public static boolean isZero(Object value) {
  118. if ((value == null) ) {
  119. return false;
  120. }
  121. String stringValue = value.toString().trim();
  122. if (stringValue.isEmpty()) {
  123. return false;
  124. }
  125. return Pattern.matches(ZERO_REG,stringValue);
  126. }
  127. public static boolean isNotNumber(Object value){
  128. return !isNumber(value);
  129. }
  130. public static BigDecimal str2BigDecimal(Object s){
  131. if(s instanceof BigDecimal){
  132. return (BigDecimal) s;
  133. }
  134. if(isNumber(s)){
  135. return new BigDecimal(s.toString());
  136. }else{
  137. return ZERO;
  138. }
  139. }
  140. public static String bigDecimalScale(Object s,int scale){
  141. return str2BigDecimal(s).setScale(scale,RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
  142. }
  143. /*默认返回零*/
  144. public static Double obj2DoubleZero(Object obj) {
  145. if(obj instanceof Double){
  146. return (Double) obj;
  147. }
  148. if(isNumber(obj)){
  149. if(obj instanceof Number){
  150. if(obj instanceof BigDecimal){
  151. return str2BigDecimal(obj).doubleValue();
  152. }
  153. return (double) obj;
  154. }
  155. return Double.parseDouble(obj.toString());
  156. }
  157. return 0D;
  158. }
  159. /*默认返回零*/
  160. public static Integer obj2IntegerZero(Object obj) {
  161. if(isNumber(obj)){
  162. if(obj instanceof Number){
  163. if(obj instanceof BigDecimal){
  164. return str2BigDecimal(obj).intValue();
  165. }
  166. return (int) obj;
  167. }
  168. return Integer.parseInt(obj.toString());
  169. }
  170. return 0;
  171. }
  172. /**
  173. * @Description 根据指定大小对LIST进行切分
  174. * @Param [list, chunkSize:每一段长度]
  175. * @return java.util.List<java.util.List<T>>
  176. * @Author yangyj
  177. * @Date 2023.07.03 13:46
  178. **/
  179. public static <T> List<List<T>> splitList(List<T> list, int chunkSize) {
  180. return IntStream.range(0, (list.size() + chunkSize - 1) / chunkSize)
  181. .mapToObj(i -> list.subList(i * chunkSize, Math.min((i + 1) * chunkSize, list.size())))
  182. .collect(Collectors.toList());
  183. }
  184. /**
  185. * @Description 深度拷贝
  186. * @Param [originalList]
  187. * @return java.util.List<T>
  188. * @Author yangyj
  189. * @Date 2023.04.28 14:18
  190. **/
  191. public static <T extends Serializable> List<T> copyList(List<T> originalList) {
  192. try {
  193. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  194. ObjectOutputStream oos = new ObjectOutputStream(baos);
  195. oos.writeObject(originalList);
  196. oos.close();
  197. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  198. ObjectInputStream ois = new ObjectInputStream(bais);
  199. @SuppressWarnings("unchecked")
  200. List<T> copiedList = (List<T>) ois.readObject();
  201. ois.close();
  202. return copiedList;
  203. } catch (Exception e) {
  204. e.printStackTrace();
  205. }
  206. return null;
  207. }
  208. public static String handleNull(Object obj) {
  209. if (null == obj) {
  210. return "";
  211. } else {
  212. return obj.toString().trim();
  213. }
  214. }
  215. public static boolean isNotEmpty(Object value) {
  216. if(value!=null){
  217. if(value instanceof List&&((List<?>) value).size()>0 ){
  218. return true;
  219. }else if(value instanceof Map&&((Map<?, ?>) value).size()>0){
  220. return true;
  221. }else {
  222. return value.toString().trim().length() > 0;
  223. }
  224. }
  225. return false;
  226. }
  227. public static boolean isEmpty(Object value){
  228. return !isNotEmpty(value);
  229. }
  230. public static List<Integer> coords2Int(String coords){
  231. Matcher mx = matcher("([A-Z]{1,3})(\\d{1,3})[~|\\-|,|#]([A-Z]{1,3})(\\d{1,3})",coords);
  232. List<Integer> list = new ArrayList<>();
  233. if(mx.find()) {
  234. list.add(Integer.parseInt(mx.group(1)));
  235. list.add(Integer.parseInt(mx.group(2)));
  236. list.add(Integer.parseInt(mx.group(3)));
  237. list.add(Integer.parseInt(mx.group(4)));
  238. }
  239. return list;
  240. }
  241. public static Matcher matcher(String regex, String value) {
  242. Pattern pattern = Pattern.compile(regex);
  243. return pattern.matcher(value);
  244. }
  245. public static Double[] scopeParse(Object dev, Object design, Object xN) {
  246. if (isNotEmpty(dev)) {
  247. Double[] result = new Double[2];
  248. double designD = Double.parseDouble(design.toString());
  249. double xND = Double.parseDouble(xN.toString());
  250. String devStr = dev.toString();
  251. devStr = devStr.replaceAll("[\\[\\]]+", "");
  252. double min = 0;
  253. double max = 0;
  254. devStr = devStr.replaceAll("\\s+", "");
  255. if (devStr.contains("≤") || devStr.contains("<=") || devStr.contains("<")||devStr.contains("≦")) {
  256. devStr = devStr.replace("≤", "").replace("<=", "").replace("≦","");
  257. max = designD + Double.parseDouble(devStr) * xND;
  258. } else if (devStr.contains("≥") || devStr.contains(">=") || devStr.contains(">")) {
  259. devStr = devStr.replace("≥", "").replace(">=", "");
  260. min = designD + Double.parseDouble(devStr) * xND;
  261. max = Double.MAX_VALUE;
  262. } else if (devStr.contains(",") || devStr.contains(",")) {
  263. String[] arr = devStr.split("[,,]");
  264. min = designD + Double.parseDouble(arr[0]) * xND;
  265. max = designD + Double.parseDouble(arr[1]) * xND;
  266. } else if (devStr.contains("%")) {
  267. devStr = devStr.replace("%", "");
  268. double devD = Math.abs(Double.parseDouble(devStr) * designD / 100);
  269. min = designD - devD;
  270. max = designD + devD;
  271. } else if (devStr.contains("±")) {
  272. devStr = devStr.replace("±", "");
  273. double devD = Math.abs(Double.parseDouble(devStr) * xND);
  274. min = designD - devD;
  275. max = designD + devD;
  276. }
  277. if(min>max){
  278. double tmp=max;
  279. max=min;
  280. min=tmp;
  281. }
  282. result[0] = min;
  283. result[1] = max;
  284. return result;
  285. }
  286. return null;
  287. }
  288. public static Integer handleObj2Integer(Object obj) {
  289. if (null == obj) {
  290. return 0;
  291. } else {
  292. double value;
  293. try {
  294. value = Double.parseDouble(obj.toString());
  295. } catch (Exception ex) {
  296. value = 0;
  297. }
  298. return (int) value;
  299. }
  300. }
  301. /**
  302. * @return java.util.List<java.lang.Object> 不能包含0
  303. * @Description specifiedRangeList
  304. * @Param [hz:频率, design:设计值, dev:偏差范围, xN 偏差范围单位和设计值单位的比值,例如毫米:厘米=0.1, scale:保存小数位, passRate:合格率[0,1]]
  305. * @Author yangyj
  306. * @Date 2022.03.31 09:16
  307. **/
  308. public static List<Object> rangeList(Object hz, Object design, Object dev, Object xN, Object scale, Object passRate) {
  309. List<Object> result = new ArrayList<>();
  310. if (isNotNull(design, dev, hz)) {
  311. if (isEmpty(scale)) {
  312. scale = 0;
  313. }
  314. if (isEmpty(passRate)) {
  315. passRate = 1;
  316. }
  317. if (isEmpty(xN)) {
  318. xN = 1;
  319. }
  320. Double[] range = scopeParse(dev, design, xN);
  321. int scaleI = Integer.parseInt(scale.toString());
  322. int min = 0, max = 0;
  323. assert range != null;
  324. if (range.length > 0) {
  325. min = (int) (range[0] * Math.pow(10, scaleI));
  326. max = (int) (range[1] * Math.pow(10, scaleI));
  327. }
  328. Random rd = new Random();
  329. int hzi = new BigDecimal(hz.toString()).multiply(new BigDecimal(passRate.toString())).setScale(0, ROUND_CEILING).intValue();
  330. int loop=200;
  331. for (int i = 0; i < hzi; i++) {
  332. BigDecimal tb = new BigDecimal(rd.nextInt(max - min + 1) + min).divide(BigDecimal.valueOf(Math.pow(10, scaleI)), scaleI, ROUND_HALF_UP);
  333. if(tb.compareTo(BigDecimal.ZERO)==0&&loop>0){
  334. loop--;
  335. i--;
  336. }else{
  337. if (scaleI > 0) {
  338. result.add(tb.doubleValue());
  339. } else {
  340. result.add(tb.intValue());
  341. }
  342. }
  343. }
  344. int total = handleObj2Integer(hz);
  345. if (total - hzi > 0) {
  346. loop=200;
  347. for (int k = 0; k < total - hzi; k++) {
  348. BigDecimal tb;
  349. if (rd.nextBoolean()) {
  350. tb = new BigDecimal(rd.nextInt(((max - min) / 2)) + max + 1).divide(BigDecimal.valueOf(Math.pow(10, scaleI)), scaleI, ROUND_HALF_UP);
  351. } else {
  352. tb = new BigDecimal(min - 1 - rd.nextInt(((max - min) / 2))).divide(BigDecimal.valueOf(Math.pow(10, scaleI)), scaleI, ROUND_HALF_UP);
  353. }
  354. if(tb.compareTo(BigDecimal.ZERO)==0&&loop>0){
  355. loop--;
  356. k--;
  357. }else {
  358. if (scaleI > 0) {
  359. result.add(tb.doubleValue());
  360. } else {
  361. result.add(tb.intValue());
  362. }
  363. }
  364. }
  365. if (result.size()>0) {
  366. Collections.shuffle(result);
  367. }
  368. }
  369. }
  370. return result;
  371. }
  372. /*是否包含链*/
  373. public static boolean notInChain(List<String> cp,String s){
  374. if(cp!=null&& isNotEmpty(s)){
  375. if(cp.size()==0){
  376. /*空结合*/
  377. return true;
  378. }else{
  379. /*没有一个已知路径包含*/
  380. return cp.stream().noneMatch(c->c.contains(s));
  381. }
  382. }
  383. return false;
  384. }
  385. public static boolean inChain(List<String> cp,String s){
  386. if(cp!=null&& isNotEmpty(s)){
  387. if(cp.size()==0){
  388. /*空结合*/
  389. return true;
  390. }else{
  391. /*没有一个已知路径包含*/
  392. return cp.stream().anyMatch(s::contains);
  393. }
  394. }
  395. return false;
  396. }
  397. public static boolean inChain(String[] cp,String s){
  398. if(cp!=null&&cp.length>0&& s!=null&&s.length()>0){
  399. return inChain(Arrays.asList(cp), s);
  400. }
  401. return false;
  402. }
  403. public static Integer getScale(Object... number) {
  404. int max = 0;
  405. if (number != null) {
  406. return getScale(scaleParam(number),1);
  407. }
  408. return max;
  409. }
  410. /**保留有效数字后面的0*/
  411. public static Integer getScaleZero(Object... number){
  412. int max = 0;
  413. if (number != null) {
  414. return getScale(scaleParam(number),0);
  415. }
  416. return max;
  417. }
  418. public static boolean containsZH(Object chars) {
  419. Matcher m = Pattern.compile("[\u4e00-\u9fa5]").matcher(handleNull(chars));
  420. return m.find();
  421. }
  422. /* public static void main(String[] args) {
  423. System.out.println(getScaleZero(152000,"±10.0"));
  424. System.out.println(getScaleZero(152000,"-10.0,10"));
  425. System.out.println(getScaleZero(152000,"-10.0,10.0"));
  426. System.out.println(getScaleZero(Double.MAX_VALUE,"-10.0,10"));
  427. System.out.println(getScaleZero(152000,"-10,10"));
  428. }*/
  429. public static List<Object> obj2List(Object obj) {
  430. List<Object> result = new ArrayList<>();
  431. if (obj != null) {
  432. List<Object> datas = new ArrayList<>();
  433. if (obj instanceof List) {
  434. datas = (List<Object>) obj;
  435. } else {
  436. datas.add(obj);
  437. }
  438. if (isNotEmpty(datas)) {
  439. for (Object e : datas) {
  440. boolean fi = isNotEmpty(e) && !containsZH(e.toString()) && (e.toString().contains("、") || e.toString().contains(",") || e.toString().contains(" ") || e.toString().contains(","));
  441. if (fi) {
  442. String s = e.toString().trim();
  443. if (s.contains(" ")) {
  444. s = s.replaceAll("\\s+", "、");
  445. }
  446. Object[] bs = s.split("[、,,]");
  447. result.addAll(Arrays.asList(bs));
  448. } else {
  449. result.add(e);
  450. }
  451. }
  452. }
  453. }
  454. return result;
  455. }
  456. public static List<Object> obj2ListNe(Object obj) {
  457. List<Object> list = obj2List(obj);
  458. return list.parallelStream().filter(BaseUtils::isNotEmpty).collect(Collectors.toList());
  459. }
  460. public static List<Object> scaleParam(Object ... number){
  461. return Arrays.stream(number).filter(BaseUtils::isNotEmpty).flatMap(e-> BaseUtils.obj2ListNe(e).stream()).distinct().map(s->s.toString().replaceAll("±","")).filter(BaseUtils::isNumber).map(e->{
  462. /*0.3999999999999986 检测到超长小数位先转double处理,再还原回String*/
  463. String tg=e.toString();
  464. int dot=tg.indexOf(".");
  465. boolean unlimited=dot>0&&(tg.length()-dot>6);
  466. if(unlimited||tg.contains("e")){
  467. return BigDecimal.valueOf(Double.parseDouble(tg)).setScale(2, RoundingMode.HALF_UP).toString();
  468. }else {
  469. return e;
  470. }
  471. }).collect(Collectors.toList());
  472. }
  473. public static final String[] SCALE_REG=new String[]{"(\\d)+.(\\d)*[0-9]","(\\d)+.(\\d)*[1-9]"};
  474. private static Integer getScale(List<Object> number,Integer zero){
  475. int max=0;
  476. if(isNotEmpty(number)){
  477. for (Object n : number) {
  478. if (isNotEmpty(n)) {
  479. String[] sa = n.toString().split(",");
  480. for (String s : sa) {
  481. Matcher m = Pattern.compile(SCALE_REG[zero]).matcher(s);
  482. if (m.find()) {
  483. int cp = new StringBuilder(m.group()).reverse().toString().indexOf(".");
  484. if (cp < 5) {
  485. max = Math.max(cp, max);
  486. }
  487. }
  488. }
  489. }
  490. }
  491. }
  492. return max;
  493. }
  494. private static final String COLUMN_REG = "^[A-Z]{0,2}$";
  495. /*列名转int*/
  496. public static int parseColumn(String column) {
  497. int value = -1;
  498. if (StringUtils.isNotEmpty(column)) {
  499. column = column.trim();
  500. if (column.matches(COLUMN_REG)) {
  501. char[] columnCh = column.toCharArray();
  502. for (char ch : columnCh) {
  503. //字母, 最长只考虑双字母的
  504. if (ch >= 65 && ch <= 90) {
  505. if (value > 0) {
  506. value = (26 * value) + (ch - 64);
  507. } else {
  508. value = ch - 64;
  509. }
  510. }
  511. }
  512. }
  513. }
  514. return value - 1;
  515. }
  516. public static String toDateStr(LocalDate date){
  517. return Optional.ofNullable(date).orElse(LocalDate.now()).format(chineseDateFm);
  518. }
  519. public static long getTimeMs(int periodYear,int periodMonth ){
  520. LocalDateTime localDateTime = LocalDateTime.of(periodYear, periodMonth, 1, 0, 0, 0);
  521. ZoneId zoneId = ZoneId.systemDefault(); // 使用系统默认时区
  522. ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
  523. return zonedDateTime.toInstant().toEpochMilli();
  524. }
  525. public static LocalDateTime toLdt(long millis) {
  526. Instant instant = Instant.ofEpochMilli(millis);
  527. ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
  528. return zonedDateTime.toLocalDateTime();
  529. }
  530. public static int dateInt(int periodYear,int periodMonth){
  531. return periodYear*100+periodMonth;
  532. }
  533. public static List<Integer> getTickUnit(int min, int max){
  534. int a1 = min / 100; // 得到最小年份
  535. int a2 = max / 100; // 得到最大年份
  536. int b1 = min % 100; // 得到最小月份
  537. int b2 = max % 100; // 得到最大月份
  538. // 确保月份在 1 到 12 之间
  539. if (b1 == 0) { b1 = 1; a1--; }
  540. if (b2 == 0) { b2 = 12; a2--; }
  541. int finalA = a1;
  542. int finalB = b1;
  543. int finalA1 = a2;
  544. int finalB1 = b2;
  545. return IntStream.rangeClosed(a1, a2)
  546. .boxed()
  547. .flatMap(year -> {
  548. int startMonth = (year == finalA) ? finalB : 1;
  549. int endMonth = (year == finalA1) ? finalB1 : 12;
  550. return IntStream.rangeClosed(startMonth, endMonth)
  551. .boxed()
  552. .map(month -> dateInt(year, month));
  553. })
  554. .collect(Collectors.toList());
  555. }
  556. }