6

私は非常に珍しい問題を抱えています。
基本的に、文字列から文字列へのマップからキーに関連付けられた値を取得しようとしています。
使用しているキーが存在することはわかっています。以前入れた紐をそのまま使ってます!

コード全体にステートメントを出力しましたが、これは私が持っているケースです...これ
が私の辞書です characterDictionary

{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\n, divideChar=÷, subjectChar=:, variableIndent=@}

最後のキー「variableIndent」が問題です!
これがコードです...

System.out.println  (   characterDictionary.get("variableIndent") );

これは不適切に出力します: null

コードをチェック、ダブルチェック、トリプルチェックしました。キー"variableIndent"と の文字列引数の
間にまったく違いはありませんが、このキーが存在しないかのように動作しています。characterDictionary.get("variableIndent")

このキーが存在すること、および 2 つの文字列が同一であることは絶対に保証できます。
ディクショナリの他のすべての要素 (私がチェックしたもの、これまでに約 3 つ) は通常どおり取得されます。「@」値を含む「variableIndent」が再生されるのはなぜですか?

辞書に「thusChar」などの非 ASCII 文字が含まれていることに気付くかもしれません。これは関連している可能性がありますか?

ありがとう
(これは非常に単純で些細な問題のように思えます。あたかも私が哀れな愚かな間違いを犯したかのようですが、それでも解決できません!)

編集:

さて、これはエンコーディングに関するものでなければなりません。
辞書から文字列キーを取得し、それを get 引数と比較しました。
印刷すると、それらは同一ですが、Javaはそれらが等しくないと言います。
キー文字列は UTF-8 でエンコードされたテキスト ファイルから取得され、引数文字列は Java Eclipse リテラルから取得されました。
ただし、キャラクターは同じです。
問題は何ですか?どうすれば解決できますか?

ありがとう!

編集:

うーん、これが実際に舞台裏で起こっていることです。
次の内容を含む UTF-8 テキスト ファイルがあります...

variableIndent,@
equalsIndent,#
spaceChar, 
newlineChar,\n
multiplyChar,×
divideChar,÷
plusChar,+
equalsChar,=
subjectChar,:
thusChar,∴

ArrayList<String>ファイルのディレクトリを渡すことにより、ファイルの各行を要素として読み取ることにより、このファイルを「ロード」します。

private static ArrayList<String> readLinesFile(String ResourceFile)  {
    ArrayList<String> Lines = new ArrayList<String>();
        try{
            InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String strLine;
            while ((strLine = br.readLine()) != null)  {
                Lines.add(strLine);  } 
            in.close();  }
        catch (Exception e)  {
            System.out.println("Error: " + e.getMessage());  } 
        return Lines;  }

ここまでは大丈夫です。
次に、この ArrayList を関数に渡し、各要素を「,」文字で分割し (個人用パッケージの関数を使用します。これは間違いなく問題ではありません)、最初の部分をキーとして新しい辞書。

private static Map<String, String> generateBaseUnits_Characters_Prefixes(ArrayList<String> FileContent)  {
    Map<String, String> BaseUnitsCache = new HashMap<String, String>();
    ArrayList<String> currentLine;
    for (int i=0; i<FileContent.size(); i++)  {
        currentLine = MiscellaneousFunctions.splitString(FileContent.get(i), ",");
        BaseUnitsCache.put(currentLine.get(0), currentLine.get(1)); }
    return BaseUnitsCache;  }

これにより、すべての問題を引き起こしている辞書が作成されます。
テキスト ファイル内の文字名に対応するキー リテラルのセットがあり、これを使用してプログラム内の辞書にアクセスします。

public static String variableIndentKey = "variableIndent";
public static String equalsIndentKey = "equalsIndent";
public static String spaceCharKey = "spaceChar";  
public static String newlineCharKey = "newlineChar";
public static String multiplyCharKey = "multiplyChar";
public static String divideCharKey = "divideChar";  
public static String plusCharKey = "plusChar";
public static String equalsCharKey = "equalsChar";  
public static String subjectCharKey = "subjectChar";
public static String thusCharKey = "thusChar";

ここに問題があります:

テキストファイルの一番上の行は、辞書の「台無し」です。これはディクショナリに追加され、keySet とディクショナリの出力形式の中で正しく表示されますが、アクセスしようとすると「null」が返されます。
(この場合は variableIndent です。variableIndent をテキスト ファイルの別の場所に配置すると、equalsIndent が台無しになるなど)

どうしたの!?
私は危険な機能を持っていますか?!
彼らは他のすべてのためにうまくいった.

ありがとう!

4

6 に答える 6

6

キーと値を含む UTF-8 テキスト ファイルを BOM なしの UTF-8 に変更します。3 バイトあります ("variableIndent" の前の UTF-8 BOM 0xEF,0xBB,0xBF) http://en.wikipedia.org/wiki/Byte_order_markを参照してください

于 2012-08-12T08:24:53.063 に答える
1

エンコーディングの問題が心配な場合 (これが問題のようです)、プロジェクトのエンコーディングが に設定されていることを確認する必要がありますUTF-8。それを確認するには、[プロジェクト] メニューに移動し、[プロパティ] を選択します。テキスト ファイルのエンコーディングを からInherited from containerに変更する必要がある場合があります。Oher: UTF-8

于 2012-08-11T08:28:38.927 に答える
0

この方法で試してみてください...

Map<String, String> map = new LinkedHashMap<String, String>();


for (Map.Entry<String, String> mp : map.entrySet()){


  System.out.println("Key: "+mp.key()+"::"+"Value: "+mp.value());


}
于 2012-08-11T09:21:00.727 に答える
0

デバッガーでコードを確認することをお勧めします。地図はあなたが思っているものとは違うと思います。

String data = "{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\\n, divideChar=÷, subjectChar=:, variableIndent=@}";
Map<String, String> map = new LinkedHashMap<String, String>();
for (String keyValue : data.substring(1, data.length() - 1).split(", ")) {
    String[] parts = keyValue.split("=", 2);
    map.put(parts[0], parts[1]);
}
System.out.println("variableIndent is " + map.get("variableIndent"));

版画

variableIndent is @

試してもらえますか

for(String key: map.keySet())
   System.out.println("'"+key+"'= "+map.get(key));
于 2012-08-11T07:08:20.397 に答える
0

うーん、このコードを試して、出力をお知らせください

for (String key : characterDictionary.keySet() ) {
System.out.println(key);
}

for ( String value :  characterDictionary.values() ) {
System.out.println(value);
}

PS: キーと値のタイプを変更したい場合があります。

于 2012-08-11T07:15:28.027 に答える
0

エンコーディングの問題だと思われる場合は、次の方法を使用して、実際のコンテンツを比較してみてください。

getBytes()両方の文字列 (マップからのキーとコード内の文字列) からすべてのバイトを取得し、出力するために使用します。

  1. バイト配列の長さ
  2. 整数としての各バイト

次にgetChars()、両方の文字列からすべての文字を取得するかcharAt()、各文字を読み取り、出力するために使用します

  1. 整数としての各文字。

これら 2 つのチェックの間に、両方の文字列がバイト レベルでどのように異なるかを把握できるはずです。ファイルが保存されている文字セットは何ですか?

編集

DataInputStream の使用が、読み取られるバイトに問題を引き起こしていると思われます。

InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));

DataInputStream の Java ドキュメントには、「データ入力ストリームを使用すると、アプリケーションは、基になる入力ストリームからプリミティブな Java データ型をマシンに依存しない方法で読み取ることができます。アプリケーションは、データ出力ストリームを使用して、後でデータ入力によって読み取ることができるデータを書き込みます。ストリーム。" ここでは DataOutputStream から読み取るのではなく、通常のファイルから読み取っています。また、InputStreamReader が使用するための InputStream が既にあります。コードを次のように変更します。

InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

編集2

テキストファイルからの文字列が3バイト長いため、これを変更することも価値があります

BaseUnitsCache.put(currentLine.get(0), currentLine.get(1));

BaseUnitsCache.put(currentLine.get(0).trim(), currentLine.get(1).trim());
于 2012-08-11T09:10:38.240 に答える