java中怎么把系统格式化_如何在java中格式化1200到1.2k

问题

我想将以下数字格式化为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

右边的数字是长整数,左边的数字是字符串。我应该如何处理这个问题。我已经为此做了很少的算法,但我认为可能已经发明了一些可以做得更好的东西,并且如果我开始处理数十亿和数万亿,则不需要额外的测试:)

其他要求:

格式最多应包含4个字符

以上意味着1.1k可以11.2k不行。相同的7.8m是可以的19.1m不是。小数点前只允许一位数具有小数点。小数点前的两位数表示小数点后的数字。

不需要四舍五入。 (附加k和m显示的数字更多是模拟量表,表示近似而不是精确的逻辑文章。因此,舍入与主要由于变量的性质无关,即使在查看缓存结果时也可以增加或减少几位数。)

#1 热门回答(103 赞)

这是一个适用于任何长值的解决方案,我发现它非常易读(核心逻辑在format方法的底部三行中完成)。

它利用TreeMap找到合适的后缀。令人惊讶的是,它比我之前编写的使用数组的解决方案更有效,并且更难以阅读。

private static final NavigableMap 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 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);

}

}

#2 热门回答(88 赞)

我知道,这看起来更像是一个C程序,但它超级轻巧!

public static void main(String args[]) {

long[] numbers = new long[]{1000, 5821, 10500, 101800, 2000000, 7800000, 92150000, 123200000, 9999999};

for(long n : numbers) {

System.out.println(n + " => " + coolFormat(n, 0));

}

}

private static char[] c = new char[]{'k', 'm', 'b', 't'};

/**

* Recursive implementation, invokes itself for each factor of a thousand, increasing the class on each invokation.

* @param n the number to format

* @param iteration in fact this is the class from the array c

* @return a String representing the number n formatted in a cool looking way.

*/

private static String coolFormat(double n, int iteration) {

double d = ((long) n / 100) / 10.0;

boolean isRound = (d * 10) %10 == 0;//true if the decimal part is equal to 0 (then it's trimmed anyway)

return (d < 1000? //this determines the class, i.e. 'k', 'm' etc

((d > 99.9 || isRound || (!isRound && d > 9.99)? //this decides whether to trim the decimals

(int) d * 10 / 10 : d + "" // (int) d * 10 / 10 drops the decimal

) + "" + c[iteration])

: coolFormat(d, iteration+1));

}

它输出:

1000 => 1k

5821 => 5.8k

10500 => 10k

101800 => 101k

2000000 => 2m

7800000 => 7.8m

92150000 => 92m

123200000 => 123m

9999999 => 9.9m

#3 热门回答(40 赞)

这里有一个使用DecimalFormat工程符号的解决方案:

public static void main(String args[]) {

long[] numbers = new long[]{7, 12, 856, 1000, 5821, 10500, 101800, 2000000, 7800000, 92150000, 123200000, 9999999};

for(long number : numbers) {

System.out.println(number + " = " + format(number));

}

}

private static String[] suffix = new String[]{"","k", "m", "b", "t"};

private static int MAX_LENGTH = 4;

private static String format(double number) {

String r = new DecimalFormat("##0E0").format(number);

r = r.replaceAll("E[0-9]", suffix[Character.getNumericValue(r.charAt(r.length() - 1)) / 3]);

while(r.length() > MAX_LENGTH || r.matches("[0-9]+\\.[a-z]")){

r = r.substring(0, r.length()-2) + r.substring(r.length() - 1);

}

return r;

}

输出:

7 = 7

12 = 12

856 = 856

1000 = 1k

5821 = 5.8k

10500 = 10k

101800 = 102k

2000000 = 2m

7800000 = 7.8m

92150000 = 92m

123200000 = 123m

9999999 = 10m

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值