• 存储单位转换工具类


    网上找了好久没找到合适的存储单位转换工具类,自己手写了一个转换工具类(大佬勿喷),分享出来,main是使用案例,可做参考!

    1. package com.glory.myselfdemo.utils;
    2. import java.math.BigDecimal;
    3. import java.math.RoundingMode;
    4. import java.util.HashMap;
    5. import java.util.Map;
    6. import java.util.regex.Matcher;
    7. import java.util.regex.Pattern;
    8. /**
    9. * @author ***
    10. */
    11. public class StorageUnitUtil {
    12. /**
    13. * bit、B、KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB、CB……
    14. */
    15. enum Unit{
    16. // 值必须由小到大递增
    17. bit,
    18. B,
    19. KB,
    20. MB,
    21. GB,
    22. TB,
    23. PB,
    24. EB,
    25. ZB,
    26. YB,
    27. BB,
    28. NB,
    29. DB,
    30. CB
    31. }
    32. /**
    33. * 换算基数:例: 1024;1000...
    34. */
    35. private final static int basic = 1024;
    36. /**
    37. * 自动转换:value>=basic,自动向大单位转换,否则返回value
    38. * @param value 转换前的值(不能为'0'且小于Double.MAX_VALUE)
    39. * @param currentUnit 转换前的单位
    40. * @return 返回转后的值和单位字符
    41. */
    42. public static String autoConvert(Number value, Unit currentUnit) {
    43. if (value.doubleValue() == 0 && value.doubleValue() < Double.MAX_VALUE) {
    44. throw new IllegalArgumentException("需要转换的值不能为0且小于Double.MAX_VALUE");
    45. }
    46. return autoToBig(value, currentUnit, null, null);
    47. }
    48. /**
    49. * 自动转换:value>=basic,自动向大单位转换,否则返回value;可定义分隔符或单位后缀
    50. * @param value 转换前的值(不能为'0'且小于Double.MAX_VALUE)
    51. * @param currentUnit 转换前的单位
    52. * @param separatorChar 值和单位中间的分隔符
    53. * @param unitSuffix 单位后面的后缀
    54. * @return 返回转后的值和(分隔符<若有>)单位(后缀<若有>)字符
    55. */
    56. public static String autoConvert(Number value, Unit currentUnit, String separatorChar, String unitSuffix) {
    57. if (value.doubleValue() == 0 && value.doubleValue() < Double.MAX_VALUE) {
    58. throw new IllegalArgumentException("需要转换的值不能为0且小于Double.MAX_VALUE");
    59. }
    60. return autoToBig(value, currentUnit, separatorChar, unitSuffix);
    61. }
    62. /**
    63. * 自动转换:valueUnit中的value>=basic,自动向大单位转换,否则返回value
    64. * @param valueUnit 转换前的值和单位字符
    65. * @return 返回转后的值和单位字符
    66. */
    67. public static String autoConvert(String valueUnit) {
    68. Map map = extractArgument(valueUnit);
    69. if (map.isEmpty()) {
    70. throw new IllegalArgumentException("参数无法解析: " + valueUnit);
    71. } else {
    72. Number number = Double.valueOf(map.get("number"));
    73. if (number.doubleValue() == 0 && number.doubleValue() < Double.MAX_VALUE) {
    74. throw new IllegalArgumentException("需要转换的值不能为0");
    75. }
    76. Unit fromUnit = Unit.valueOf(map.get("unit"));
    77. return autoToBig(number, fromUnit, null, null);
    78. }
    79. }
    80. /**
    81. * 自动转换:valueUnit中的value>=basic,自动向大单位转换,否则返回value;可定义分隔符或单位后缀
    82. * @param valueUnit 转换前的值和单位字符
    83. * @param separatorChar 值和单位中间的分隔符
    84. * @param unitSuffix 单位后面的后缀
    85. * @return 返回转后的值和(分隔符<若有>)单位(后缀<若有>)字符
    86. */
    87. public static String autoConvert(String valueUnit, String separatorChar, String unitSuffix) {
    88. Map map = extractArgument(valueUnit);
    89. if (map.isEmpty()) {
    90. throw new IllegalArgumentException("参数无法解析: " + valueUnit);
    91. } else {
    92. Number number = Double.valueOf(map.get("number"));
    93. if (number.doubleValue() == 0 && number.doubleValue() < Double.MAX_VALUE) {
    94. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    95. }
    96. Unit fromUnit = Unit.valueOf(map.get("unit"));
    97. return autoToBig(number, fromUnit, separatorChar, unitSuffix);
    98. }
    99. }
    100. /**
    101. * 指定转换:指定转换后的单位,valueUnit中的value向指定单位换算成对应的值
    102. * @param valueUnit 转换前的值和单位字符
    103. * @param toUnit 转换后的单位
    104. * @return 返回转后的值和单位字符
    105. */
    106. public static String customConvert(String valueUnit, Unit toUnit) {
    107. Map map = extractArgument(valueUnit);
    108. String result;
    109. if (map.isEmpty()) {
    110. throw new IllegalArgumentException("参数无法解析: " + valueUnit);
    111. } else {
    112. Number number = Double.valueOf(map.get("number"));
    113. if (number.doubleValue() == 0 && number.doubleValue() < Double.MAX_VALUE) {
    114. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    115. }
    116. Unit fromUnit = Unit.valueOf(map.get("unit"));
    117. int fromOrdinal = fromUnit.ordinal();
    118. int toOrdinal = toUnit.ordinal();
    119. if (fromOrdinal == toOrdinal) {
    120. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    121. }
    122. // big to small
    123. if (fromOrdinal > toOrdinal) {
    124. result = customToSmall(number, fromUnit, toUnit, null, null);
    125. } else {
    126. result = autoToBig(number, fromUnit, null, null);
    127. }
    128. }
    129. return result;
    130. }
    131. /**
    132. * 指定转换:指定转换后的单位,valueUnit中的value向指定单位换算成对应的值;可定义分隔符或单位后缀
    133. * @param valueUnit 转换前的值和单位字符
    134. * @param toUnit 转换后的单位
    135. * @param separatorChar 值和单位中间的分隔符
    136. * @param unitSuffix 单位后面的后缀
    137. * @return 返回转后的值和(分隔符<若有>)单位(后缀<若有>)字符
    138. */
    139. public static String customConvert(String valueUnit, Unit toUnit, String separatorChar, String unitSuffix) {
    140. Map map = extractArgument(valueUnit);
    141. String result;
    142. if (map.isEmpty()) {
    143. throw new IllegalArgumentException("参数无法解析: " + valueUnit);
    144. } else {
    145. Number number = Double.valueOf(map.get("number"));
    146. if (number.doubleValue() == 0 && number.doubleValue() < Double.MAX_VALUE) {
    147. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    148. }
    149. Unit fromUnit = Unit.valueOf(map.get("unit"));
    150. int fromOrdinal = fromUnit.ordinal();
    151. int toOrdinal = toUnit.ordinal();
    152. if (fromOrdinal == toOrdinal) {
    153. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    154. }
    155. // big to small
    156. if (fromOrdinal > toOrdinal) {
    157. result = customToSmall(number, fromUnit, toUnit, separatorChar, unitSuffix);
    158. } else {
    159. result = autoToBig(number, fromUnit, separatorChar, unitSuffix);
    160. }
    161. }
    162. return result;
    163. }
    164. /**
    165. * 指定转换:指定转换后的单位,value向指定单位换算成对应的值
    166. * @param value 转换前的值
    167. * @param currentUnit 转换前的单位
    168. * @param toUnit 转换后的单位
    169. * @return 返回转后的值和单位字符
    170. */
    171. public static String customConvert(Number value,Unit currentUnit, Unit toUnit) {
    172. String result;
    173. if (value.doubleValue() == 0 && value.doubleValue() < Double.MAX_VALUE) {
    174. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    175. }
    176. int fromOrdinal = currentUnit.ordinal();
    177. int toOrdinal = toUnit.ordinal();
    178. if (fromOrdinal == toOrdinal) {
    179. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    180. }
    181. // big to small
    182. if (fromOrdinal > toOrdinal) {
    183. result = customToSmall(value, currentUnit, toUnit, null, null);
    184. } else {
    185. result = autoToBig(value, currentUnit, null, null);
    186. }
    187. return result;
    188. }
    189. /**
    190. *
    191. * 指定转换:指定转换后的单位,value向指定单位换算成对应的值;可定义分隔符或单位后缀
    192. * @param value 转换前的值
    193. * @param currentUnit 转换前的单位
    194. * @param toUnit 转换后的单位
    195. * @param separatorChar 值和单位中间的分隔符
    196. * @param unitSuffix 单位后面的后缀
    197. * @return 返回转换后的值和(分隔符<若有>)单位(后缀<若有>)字符
    198. */
    199. public static String customConvert(Number value, Unit currentUnit, Unit toUnit, String separatorChar, String unitSuffix) {
    200. String result;
    201. if (value.doubleValue() == 0 && value.doubleValue() < Double.MAX_VALUE) {
    202. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    203. }
    204. int fromOrdinal = currentUnit.ordinal();
    205. int toOrdinal = toUnit.ordinal();
    206. if (fromOrdinal == toOrdinal) {
    207. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    208. }
    209. // big to small
    210. if (fromOrdinal > toOrdinal) {
    211. result = customToSmall(value, currentUnit, toUnit, separatorChar, unitSuffix);
    212. } else {
    213. result = autoToBig(value, currentUnit, separatorChar, unitSuffix);
    214. }
    215. return result;
    216. }
    217. /**
    218. * 指定转换:指定转换后的单位,value向指定单位换算成对应的值并返回
    219. * @param value 转换前的值
    220. * @param currentUnit 转换前的单位
    221. * @param toUnit 转换后的单位
    222. * @return 返回转换后的值 java.lang.Number
    223. */
    224. public static Number getNumberConvert(Number value,Unit currentUnit, Unit toUnit) {
    225. Number number;
    226. if (value.doubleValue() == 0 && value.doubleValue() < Double.MAX_VALUE) {
    227. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    228. }
    229. int fromOrdinal = currentUnit.ordinal();
    230. int toOrdinal = toUnit.ordinal();
    231. if (fromOrdinal == toOrdinal) {
    232. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    233. }
    234. // big to small
    235. if (fromOrdinal > toOrdinal) {
    236. number = customToSmall(value, currentUnit, toUnit);
    237. } else {
    238. number = autoToBig(value, currentUnit);
    239. }
    240. return number;
    241. }
    242. /**
    243. * 指定转换:指定转换后的单位,valueUnit中的value向指定单位换算成对应的值并返回
    244. * @param valueUnit 转换前的值和单位字符
    245. * @param toUnit 转换后的单位
    246. * @return 返回转换后的值 java.lang.Number
    247. */
    248. public static Number getNumberConvert(String valueUnit, Unit toUnit) {
    249. Map map = extractArgument(valueUnit);
    250. Number number;
    251. if (map.isEmpty()) {
    252. throw new IllegalArgumentException("参数无法解析: " + valueUnit);
    253. } else {
    254. number = Double.valueOf(map.get("number"));
    255. if (number.doubleValue() == 0 && number.doubleValue() < Double.MAX_VALUE) {
    256. throw new IllegalArgumentException("需要转换的值不能为0或超出计算范围");
    257. }
    258. Unit fromUnit = Unit.valueOf(map.get("unit"));
    259. int fromOrdinal = fromUnit.ordinal();
    260. int toOrdinal = toUnit.ordinal();
    261. if (fromOrdinal == toOrdinal) {
    262. throw new IllegalArgumentException("当前单位和转换结果的目标单位不能相同");
    263. }
    264. // big to small
    265. if (fromOrdinal > toOrdinal) {
    266. number = customToSmall(number, fromUnit, toUnit);
    267. } else {
    268. number = autoToBig(number, fromUnit);
    269. }
    270. }
    271. return number;
    272. }
    273. private static Number customToSmall(Number number, Unit fromUnit, Unit toUnit){
    274. final int enumIdx = 0;
    275. final int special = 8;
    276. final int resultScale = 2;
    277. int fromOrdinal = fromUnit.ordinal();
    278. int toOrdinal = toUnit.ordinal();
    279. int level = fromOrdinal - toOrdinal;
    280. BigDecimal value = BigDecimal.valueOf(number.doubleValue());
    281. BigDecimal basicDec = BigDecimal.valueOf(basic);
    282. BigDecimal specialDec = BigDecimal.valueOf(special);
    283. if (toOrdinal == enumIdx) {
    284. level -= 1;
    285. value = value.multiply(specialDec);
    286. }
    287. for (int i = 1; i <= level; i++) {
    288. value = value.multiply(basicDec);
    289. }
    290. value = value.setScale(resultScale, RoundingMode.HALF_UP);
    291. return formatToLong(value);
    292. }
    293. private static String customToSmall(Number number, Unit fromUnit, Unit toUnit, String separatorChar, String unitSuffix) {
    294. final int enumIdx = 0;
    295. final int special = 8;
    296. final int resultScale = 2;
    297. int fromOrdinal = fromUnit.ordinal();
    298. int toOrdinal = toUnit.ordinal();
    299. int level = fromOrdinal - toOrdinal;
    300. BigDecimal value = BigDecimal.valueOf(number.doubleValue());
    301. BigDecimal basicDec = BigDecimal.valueOf(basic);
    302. BigDecimal specialDec = BigDecimal.valueOf(special);
    303. if (toOrdinal == enumIdx) {
    304. level -= 1;
    305. value = value.multiply(specialDec);
    306. }
    307. for (int i = 1; i <= level; i++) {
    308. value = value.multiply(basicDec);
    309. }
    310. value = value.setScale(resultScale, RoundingMode.HALF_UP);
    311. Number resultVal = formatToLong(value);
    312. String result = String.valueOf(resultVal);
    313. if (separatorChar != null && !"".equals(separatorChar) && separatorChar.length() > 0) {
    314. result = result.concat(separatorChar);
    315. }
    316. result = result.concat(toUnit.name());
    317. if (unitSuffix != null && !"".equals(unitSuffix) && unitSuffix.length() > 0) {
    318. result = result.concat(unitSuffix);
    319. }
    320. return result;
    321. }
    322. private static Map extractArgument(String valUnit) {
    323. Map map = new HashMap<>();
    324. Unit[] units = Unit.values();
    325. // String unitsStr = Arrays.stream(units).map(Enum::name).collect(Collectors.joining("|"));
    326. StringBuilder builder = new StringBuilder();
    327. for (Unit unit : units) {
    328. String name = unit.name();
    329. builder.append(name);
    330. if (unit.ordinal() < (units.length - 1)) {
    331. builder.append("|");
    332. }
    333. }
    334. final String regex = "^(\\d+[.]?\\d*)\\s*(" + builder + ")$";
    335. Pattern pattern = Pattern.compile(regex);
    336. Matcher matcher = pattern.matcher(valUnit);
    337. while (matcher.find()) {
    338. map.put("number", matcher.group(1));
    339. map.put("unit", matcher.group(2));
    340. }
    341. return map;
    342. }
    343. private static Unit getUnitByOrdinal(int ordinal) {
    344. Unit[] units = Unit.values();
    345. for (Unit unit : units) {
    346. if (unit.ordinal() == ordinal) {
    347. return unit;
    348. }
    349. }
    350. throw new IllegalArgumentException("未录入该存储单位");
    351. }
    352. private static Number autoToBig(Number val, Unit fromUnit) {
    353. final int enumIdx = 0;
    354. int fromOrdinal = fromUnit.ordinal();
    355. if (enumIdx == fromOrdinal) {
    356. val = bitToByte(val);
    357. fromOrdinal += 1;
    358. }
    359. // 计算时尽量保持精确度 保留10位小数s
    360. final int scale = 10;
    361. // 返回时保留2位小数
    362. final int resultScale = 2;
    363. BigDecimal smallVal = BigDecimal.valueOf(val.doubleValue());
    364. BigDecimal basicVal = BigDecimal.valueOf(basic);
    365. while (smallVal.compareTo(basicVal) >= 0 && (fromOrdinal < Unit.values().length - 1)) {
    366. smallVal = smallVal.divide(basicVal, scale, RoundingMode.HALF_UP);
    367. fromOrdinal += 1;
    368. }
    369. smallVal = smallVal.setScale(resultScale, RoundingMode.HALF_UP);
    370. return formatToLong(smallVal);
    371. }
    372. private static String autoToBig(Number val, Unit fromUnit, String separatorChar, String unitSuffix) {
    373. final int enumIdx = 0;
    374. int fromOrdinal = fromUnit.ordinal();
    375. if (enumIdx == fromOrdinal) {
    376. val = bitToByte(val);
    377. fromOrdinal += 1;
    378. }
    379. // 计算时尽量保持精确度 保留10位小数s
    380. final int scale = 10;
    381. // 返回时保留2位小数
    382. final int resultScale = 2;
    383. BigDecimal smallVal = BigDecimal.valueOf(val.doubleValue());
    384. BigDecimal basicVal = BigDecimal.valueOf(basic);
    385. while (smallVal.compareTo(basicVal) >= 0 && (fromOrdinal < Unit.values().length - 1)) {
    386. smallVal = smallVal.divide(basicVal, scale, RoundingMode.HALF_UP);
    387. fromOrdinal += 1;
    388. }
    389. Unit toUnit = getUnitByOrdinal(fromOrdinal);
    390. smallVal = smallVal.setScale(resultScale, RoundingMode.HALF_UP);
    391. Number number = formatToLong(smallVal);
    392. String result = String.valueOf(number);
    393. if (separatorChar != null && !"".equals(separatorChar) && separatorChar.length() > 0) {
    394. result = result.concat(separatorChar);
    395. }
    396. result = result.concat(toUnit.name());
    397. if (unitSuffix != null && !"".equals(unitSuffix) && unitSuffix.length() > 0) {
    398. result = result.concat(unitSuffix);
    399. }
    400. return result;
    401. }
    402. private static Number bitToByte(Number bitSize) {
    403. final int basic = 8;
    404. final int scale = 10;
    405. double bitDouble = bitSize.doubleValue();
    406. if (bitDouble == 0) {
    407. return bitSize;
    408. }
    409. BigDecimal bitDec = BigDecimal.valueOf(bitDouble);
    410. BigDecimal basicDec = BigDecimal.valueOf(basic);
    411. BigDecimal byteDec = bitDec.divide(basicDec, scale, RoundingMode.HALF_UP);
    412. return formatToLong(byteDec);
    413. }
    414. private static Number formatToLong(Number val) {
    415. double d = val.doubleValue();
    416. long l = val.longValue();
    417. if (d == l) {
    418. return l;
    419. }
    420. return val;
    421. }
    422. public static void main(String[] args) {
    423. String s1 = autoConvert(10240, Unit.KB);
    424. System.out.println("s1 = " + s1);
    425. String s2 = autoConvert(8192, Unit.KB, " ", "/s");
    426. System.out.println("s2 = " + s2);
    427. String s3 = autoConvert("10240TB");
    428. System.out.println("s3 = " + s3);
    429. String s4 = autoConvert("1023GB", " ", "/每天");
    430. System.out.println("s4 = " + s4);
    431. String s5 = customConvert("1TB", Unit.bit);
    432. System.out.println("s5 = " + s5);
    433. String s6 = customConvert(1, Unit.TB, Unit.bit);
    434. System.out.println("s6 = " + s6);
    435. String s7 = customConvert("1CB", Unit.YB);
    436. System.out.println("s7 = " + s7);
    437. String s8 = autoConvert(9.8938489077261e+27,Unit.bit);
    438. System.out.println("s8 = " + s8);
    439. String s9 = customConvert(1024, Unit.B, Unit.bit, " ", null);
    440. System.out.println("s9 = " + s9);
    441. String s10 = customConvert("1024KB", Unit.MB, " ", "/s");
    442. System.out.println("s10 = " + s10);
    443. Number n1 = getNumberConvert("1024GB", Unit.MB);
    444. System.out.println("n1 = " + n1);
    445. Number n2 = getNumberConvert(1024, Unit.KB, Unit.MB);
    446. System.out.println("n2 = " + n2);
    447. }
    448. }

  • 相关阅读:
    WPF中获取TreeView以及ListView获取其本身滚动条进行滚动
    【DS基础】栈与队列
    数据结构:AVL树的旋转(高度平衡树)
    【VIO】练习1 IMU标定
    【操作系统 | Linux】 文件管理四件套(切换,创建删除,复制移动)
    五.实战软件部署 4-5MYSQL 5.7版本在ubuntu(WSL环境)安装&MYSQL 8.0版本在ubuntu(WSL环境)安装
    产品化的GPT,能否为“百模大战”照亮未来?
    一、CC2530开发环境搭建
    UE5 C++报错:is not currently enabled for Live Coding
    Servlet
  • 原文地址:https://blog.csdn.net/Java_Glory/article/details/125897332