如何在 Java 中将 1200 格式化为 1.2k [英] How to go about formatting 1200 to 1.2k in java
问题描述
我想用 java 将以下数字格式化为它们旁边的数字:
I'd like to format following numbers into the numbers next to them with java:
1000 to 1k
5821 to 5.8k
10500 to 10k
101800 to 101k
2000000 to 2m
7800000 to 7.8m
92150000 to 92m
123200000 to 123m
右边的数字是长整数或整数,左边的数字是字符串.我应该如何处理这个.我已经为此做了很少的算法,但我认为可能已经发明了一些可以做得更好的东西,如果我开始处理数十亿和万亿,则不需要额外的测试:)
The number on the right will be long or integer the number on the left will be string. How should I approach this. I already did little algorithm for this but I thought there might be already something invented out there that does nicer job at it and doesn't require additional testing if I start dealing with billions and trillions :)
其他要求:
- 格式应最多包含 4 个字符
- 以上表示 1.1k 可以,11.2k 不行.7.8m 相同,19.1m 不是.小数点前只允许一位数有小数点.小数点前两位表示不是小数点后的数字.
- 不需要四舍五入.(显示的带有 k 和 m 的数字更多是模拟仪表,表示近似值,而不是精确的逻辑文章.因此,舍入无关紧要,主要是由于变量的性质,即使在查看缓存结果时也可以增加或减少几位数字.)
推荐答案
这是一个适用于任何长值的解决方案,我觉得它非常易读(核心逻辑在 format
方法的底部三行中完成).
Here is a solution that works for any long value and that I find quite readable (the core logic is done in the bottom three lines of the format
method).
它利用 TreeMap
来找到合适的后缀.与我之前编写的使用数组且更难阅读的解决方案相比,它的效率出奇地高.
It leverages TreeMap
to find the appropriate suffix. It is surprisingly more efficient than a previous solution I wrote that was using arrays and was more difficult to read.
private static final NavigableMap<Long, String> suffixes = new TreeMap<> ();
static {
suffixes.put(1_000L, "k");
suffixes.put(1_000_000L, "M");
suffixes.put(1_000_000_000L, "G");
suffixes.put(1_000_000_000_000L, "T");
suffixes.put(1_000_000_000_000_000L, "P");
suffixes.put(1_000_000_000_000_000_000L, "E");
}
public static String format(long value) {
//Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
if (value == Long.MIN_VALUE) return format(Long.MIN_VALUE + 1);
if (value < 0) return "-" + format(-value);
if (value < 1000) return Long.toString(value); //deal with easy case
Entry<Long, String> e = suffixes.floorEntry(value);
Long divideBy = e.getKey();
String suffix = e.getValue();
long truncated = value / (divideBy / 10); //the number part of the output times 10
boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10);
return hasDecimal ? (truncated / 10d) + suffix : (truncated / 10) + suffix;
}
测试代码
public static void main(String args[]) {
long[] numbers = {0, 5, 999, 1_000, -5_821, 10_500, -101_800, 2_000_000, -7_800_000, 92_150_000, 123_200_000, 9_999_999, 999_999_999_999_999_999L, 1_230_000_000_000_000L, Long.MIN_VALUE, Long.MAX_VALUE};
String[] expected = {"0", "5", "999", "1k", "-5.8k", "10k", "-101k", "2M", "-7.8M", "92M", "123M", "9.9M", "999P", "1.2P", "-9.2E", "9.2E"};
for (int i = 0; i < numbers.length; i++) {
long n = numbers[i];
String formatted = format(n);
System.out.println(n + " => " + formatted);
if (!formatted.equals(expected[i])) throw new AssertionError("Expected: " + expected[i] + " but found: " + formatted);
}
}
这篇关于如何在 Java 中将 1200 格式化为 1.2k的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!