999~999 1000~1k
150万~1.5m
など、精度をまったく失わないようにしたい
また、それらを元の値に戻す必要があります
1.5m~1500000など
それが行く最高は最大11桁です
ありがとう
これはどう:
import static java.lang.Double.parseDouble;
import static java.util.regex.Pattern.compile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
...
private static final Pattern REGEX = compile("(\\d+(?:\\.\\d+)?)([KMG]?)");
private static final String[] KMG = new String[] {"", "K", "M", "G"};
static String formatDbl(double d) {
int i = 0;
while (d >= 1000) { i++; d /= 1000; }
return d + KMG[i];
}
static double parseDbl(String s) {
final Matcher m = REGEX.matcher(s);
if (!m.matches()) throw new RuntimeException("Invalid number format " + s);
int i = 0;
long scale = 1;
while (!m.group(2).equals(KMG[i])) { i++; scale *= 1000; }
return parseDouble(m.group(1)) * scale;
}
static String[] prefixes = {"k","M","G"};
// Formats a double to a String with SI units
public static String format(double d) {
String result = String.valueOf(d);
// Get the prefix to use
int prefixIndex = (int) (Math.log10(d) / Math.log10(10)) / 3;
// We only have a limited number of prefixes
if (prefixIndex > prefixes.length)
prefixIndex = prefixes.length;
// Divide the input to the appropriate prefix and add the prefix character on the end
if (prefixIndex > 0)
result = String.valueOf(d / Math.pow(10,prefixIndex*3)) + prefixes[prefixIndex-1];
// Return result
return result;
}
// Parses a String formatted with SI units to a double
public static double parse(String s) {
// Retrieve the double part of the String (will throw an exception if not a double)
double result = Double.parseDouble(s.substring(0,s.length()-1));
// Retrieve the prefix index used
int prefixIndex = Arrays.asList(prefixes).indexOf(s.substring(s.length()-1)) + 1;
// Multiply the input to the appropriate prefix used
if (prefixIndex > 0)
result = result * Math.pow(10,prefixIndex*3);
return result;
}
それらが最終的なものでない場合は、java.lang.Integer などを拡張して toString() メソッドをオーバーライドできます。java.lang.Number サブクラスを作成する価値はありますか? おそらくそうではありません。コンポジションを使用して MyInteger、MyFloat などの独自のクラスを作成し (数値を保持する属性があります)、 toString() メソッドをオーバーライドして、必要な形式を返すことができます。
逆に、文字列の数値 ("1m" など) を含むオブジェクトを作成する MyXXX クラスにファクトリ メソッドを作成できます。
良いことは、そのような作業が単体テストに適していることです。
NumberFormat サブクラスを直接使用することで、おそらく必要なものを取得できますが、使用方法によっては、上記の設計の方が優れている場合があります。