2009-05-20 3 views
34

文字列として得られたいくつかの数値をDoublesに変換したいが、これらの数値は米国の標準ロケールではなく、別の数値に変換されている。どうやってやるの?特定のロケールを使用して文字列をJavaでDoubleに変換するにはどうすればよいですか?

+2

私はそれらの2つだけupvoted 6つの答えを、持っているが、それらのすべてが正しいです。月桂冠は無限の答えに行く。 –

答えて

59

お試しjava.text.NumberFormat Javadocsから:

異なるロケールの番号をフォーマットするには、getInstanceの呼び出しで指定します。

NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH); 

また、数字を解析するのNumberFormatを使用することができます。

myNumber = nf.parse(myString); 

Numberを返しparse()

double myNumber = nf.parse(myString).doubleValue(); 

parse()ことがnullを返すことはありませんので、これはNullPointerExceptionを起こさないことができますので、doubleを取得するには、myNumber.doubleValue()を呼び出す必要があります。代わりに、parseは、失敗した場合にチェックされたParseExceptionをスローします。

編集:私はもともとdoubleに変換する別の方法があったことを言った:Doubleに結果をキャストとアンボクシングを使用しています。私は汎用目的のNumberFormatのインスタンスが(getInstanceのJavadocで)使用されていたので、常にDoubleを返すと考えました。しかしDJClayworthは、のJavadoc(parse(String)と呼ばれます)では、可能であればLongが返されると指摘しています。そのため、結果をDoubleにキャストするは安全ではありません。試してはいけません。
ありがとう、DJClayworth!

+0

答えに.doubleValue()メソッドを追加すれば、それを受け入れます。 –

+0

私はNumberFormat.parse()がDoubleを返すと約束するものは何もありません。実際には、値がLongに含まれていればLongを返し、メソッド1はClassCastExeptionをスローします。 – DJClayworth

+8

FR_frロケールは、区切り記号として非改行スペース(U + 00A0)を使用するため、フランス語に注意してください。これにより、セパレータが「通常の」スペース(U + 0020)(標準的なキーボードスペースなど)の場合と同じようにテキストが表示されます。結果は、 "3 141,59"のように正しくフォーマットされているように見える番号文字列が3141.59の代わりに3に解析されるサイレントエラーです。文字列は、正しく解析するには "3 \ u00A0141,59"のように指定する必要があります。また、ParsePositionでこのメソッドを使用し、解析後にParsePosition.getIndex()== inputString.length()をチェックすることをお勧めします。 – Phil

1

これは、java.text.DecimalFormatを使用しても問題ありません。

1

使用NumberFormat.getNumberInstance(ロケール)

0

あなたはそれがあるロケールを知っていますか?次に使用できる

DecimalFormat format = DecimalFormat.getInstance(theLocale); 
format.parse(yourString); 

これは、科学記号、パーセンテージ記号または通貨記号付き文字列でも機能します。

+1

DecimalFormat.getInstanceは実際にDecimalFormatを返すことは保証されていません。 NumberFormatのサブクラスを返すことが保証されているNumberFormat.getInstanceを実際に呼び出しています。 NumberFormatのドキュメントから: "さらに書式や解析を制御したい場合や、ユーザーにコントロールを与えたい場合は、ファクトリメソッドから取得したNumberFormatをDecimalFormatにキャストしてみてください。これは大多数のあなたが珍しいものに遭遇した場合に備えて、tryブロックに入れてください。 –

+0

あなたは本当に正しいです。私のコードでは、実際に使用しています DecimalFormat format =(DecimalFormat)DecimalFormat.getInstance(theLocale); すべてのロケールで動作しないことがわかりませんでした... – Fortega

5

NumberFormatは行く方法ですが、データが100%未満の場合には、その特殊性を認識する必要があります。あなたの入力が信頼できる

http://www.ibm.com/developerworks/java/library/j-numberformat/index.html

ならば、あなたはそれを心配する必要はありません。

は、私は、次の便利を見つけました。ただ、Javaのプログラミングを学習

doubleExample.java

import java.io.BufferedReader; 

import java.io.IOException; 

import java.io.InputStreamReader; 

public class doubleExample { 

     public static void main(String[] args) { 

       Double myDouble = new Double("0"); 
       System.out.println("Please enter a number:"); 

       try 
       { 
         //get the number from console 
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
         myDouble = Double.parseDouble(br.readLine()); 
       } 
       //if invalid value was entered 
       catch(NumberFormatException ne) 
       { 
         System.out.println("Invalid value" + ne); 
         System.exit(0); 
       } 
    catch(IOException ioe) 
       { 
         System.out.println("IO Error :" + ioe); 
         System.exit(0); 
       } 

       System.out.println("Double value is " + myDouble); 
     } 
} 
-3

あなたはStringDoubleに変換するために、parseDoubleを使用する方法です。同様の質問がありました。私の教科書では、このようなものが見つかりました:

Scanner sc = new Scanner(string); 
double number = sc.nextDouble(); 

を本は、スキャナは自動的に文字列variabelに何デコードし、Scannerクラスが自動的に設定されたロケールの言語に適応していることと言うシステムロケールがデフォルトであることが、それは他のものに簡単に設定できます。

私はこのように私の問題を解決しました。おそらく、これは解析の代わりに上記の問題のために働く可能性がありますか?

追加:私はこのメソッドが好きだった理由は、入力のためにスイングdialougeボックスを使用し、文字列を解析すると倍精度化するときにNumberFormatExceptionを取得したという事実でした。 Scannerはすべてのフォーマットを処理できる一方で、解析ではUS番号の書式を排他的に使用することが判明しました。スキャナはカンマ(、)小数点記号でも入力を完璧に処理しました。最も投票された答えが解析を使用するので、私は実際にこの特定の問題をどのように解決するのか分かりません。あなたは米国のフォーマットであなたの番号を入力し、ロケールフォーマットに変換する必要があります。これは数字キーボードにカンマがついているときはむしろ不便です。

今、あなたはすべての部分に私を細断処理は自由です;)

+0

以前の受け入れられた、高いupvoted回答にあなたの答えは何を追加しますか?あなたのコードを少しコメントする気に? – Yaroslav

+3

この回答は* DOWNRIGHT INCORRECT *です。Java APIのドキュメントによると、 'parseDouble'は' valueOf'と同じ規則を使います。これはJava * Language * double形式です。つまり、現在のロケールに関係なく、「1,0」を2倍として解析しません。さらに、特定の*ロケールを渡す方法はありません(ロケールをまったく使用しないので意味があります)。 –

3

:ここ

+1

java.util.Scannerのコメント(少なくともAndroidスタジオでは)はちょっと面白いです... ' 正規表現の助けを借りて、プリミティブ型と文字列のテキスト文字列を解析するパーサです。このクラスは、見た目ほど役に立つものではありません。 マシン間の通信には非常に非効率的です。 JSON、protobufs、またはXMLを使用してください。非常に単純な使い方では、String#splitを使用することがあります。人間からの入力の場合、ロケール固有の正規表現を使用すると、高価なだけでなく、予測できないものになります。 –