2012-08-11 7 views
5

Mam bardzo nietypowy problem.
Zasadniczo próbuję uzyskać wartość skojarzoną z kluczem z mapy ciągów znaków do ciągów.
Wiem, że klucz, którego używam, jest obecny; Używam tego samego ciągu, który użyłem do jego wstawienia!Java Map zwraca wartość null dla klucza bieżącego

mam instrukcje print całym moim kodu, a to jest sprawa mam ...
Oto mój słownik characterDictionary

{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\n, divideChar=÷, subjectChar=:, [email protected]} 

Ostatnim kluczowym „variableIndent” jest kłopot!
Oto kod ...

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

który niewłaściwie wyjść: null

Sprawdziłem, podwójne i potrójne sprawdzone sprawdzone mojego kodu.
Nie ma absolutnie żadnej różnicy między kluczowego „variableIndent” i argument string characterDictionary.get("variableIndent"), ale to zachowuje się tak, jakby ten klucz nie był obecny.

Mogę bezwzględnie zagwarantować, że ten klucz jest obecny i że oba ciągi są identyczne.
Wszystkie pozostałe elementy (te, które sprawdziłem, około 3 dotychczas) ze słownika są pobierane jak zwykle. Dlaczego "variableIndent" ma wartość "@"?

Możesz zauważyć, że słownik zawiera znaki inne niż ASCII, np. "ThusChar". Czy to może być powiązane?

Dzięki
(To wydaje się bardzo prosty i banalny problem, jakby Zrobiłem trochę żałośnie głupi błąd, ale jeszcze nie mogę go rozwiązać!)

EDIT:

Okej, to musi być coś o kodowaniu.
Wziąłem klucz łańcucha ze słownika i porównałem go z argumentem get.
Po wydrukowaniu są identyczne, ale java mówi, że nie są równe.
Kluczowy ciąg pochodzi z zakodowanego pliku tekstowego UTF-8, podczas gdy ciąg argumentów pochodzi z dosłownego Eclipse języka Java.
Jednak znaki są identyczne.
Na czym polega problem i jak mogę go rozwiązać?

Dzięki!

EDIT:

Hmmm, tutaj jest to, co faktycznie dzieje się za kulisami.
Mam plik tekstowy UTF-8, który zawiera następujące treści ...

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

ja „obciążenie” ten plik czytając w każdym wierszu pliku jako element ArrayList<String>, przekazując katalog pliku:

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; } 

Wszystko jest w porządku, nawet tutaj.
Następnie przekazuję tę tablicę ArrayList do funkcji, która dzieli każdy element przez znak "," (przy użyciu funkcji z osobistego pakietu, to zdecydowanie nie jest problem) i dodaje pierwszą część jako klucz do drugiego w nowy słownik.

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; } 

To powoduje, że słownik powoduje wszystkie problemy.
Mam zestaw literałów kluczowych, które odpowiadają nazwom postaci w plikach tekstowych, których używam, aby uzyskać dostęp do słownika w programie.

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"; 

tutaj jest problem:

górna linia tekstowego 'śruby w górę' w słowniku. Został dodany do słownika i poprawnie wyświetla się w zestawie kluczy i drukowanym formacie słownika, ale próba dostępu do niego zwraca "null".
(W tym przypadku, to variableIndent. Jeśli mogę umieścić variableIndent gdzieś w pliku tekstowym, equalsIndent śruby do góry, etc)

Co się dzieje !?
Czy mam podejrzaną funkcję ?!
Sprawdzili się dobrze we wszystkim innym.

Dzięki!

+0

W celu zagwarantowania, że ​​ten klucz jest obecny, iteracyjne nad wszystkie klucze w tej mapie i wydrukować swoją wartość. –

+0

Czy możesz pokazać niektóre, które odtwarzają zachowanie? – assylias

+0

edytował OP. Wierzcie, że jest to problem z kodowaniem między plikiem tekstowym a Eclipse. –

Odpowiedz

6

zmienić plik tekstowy UTF-8 zawierający klucz i wartość UTF-8 bez LM. Istnieją trzy bajty (UTF-8 BOM 0xEF, 0xBB, 0xBF przed „variableIndent”) zobaczyć http://en.wikipedia.org/wiki/Byte_order_mark

+0

Jak na Ziemi mam to zrobić? –

+1

można używać ultraedit lub notatnika ++ – andy

+0

@AntiEarth To może pomóc ... W każdym razie, jeśli znajdziesz rozwiązanie, proszę poinformuj mnie również. Jestem ciekaw, jak rozwiążesz tak dziwny problem. Niestety, nie ma automatycznego sposobu odrzucania pytań na temat SO. – dantuch

0

Proponuję, abyś spojrzał na swój kod w debugerze. Podejrzewam, że mapa nie jest taka, jak myślisz.

String data = "{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\\n, divideChar=÷, subjectChar=:, [email protected]}"; 
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")); 

drukuje

variableIndent is @ 

można spróbować

for(String key: map.keySet()) 
    System.out.println("'"+key+"'= "+map.get(key)); 
+0

drukowane keyset i otrzymane '[thusChar, spaceChar, plusChar, equalsIndent, multiplyChar, equalsChar, newlineChar, divideChar, subjectChar, variableIndent]' –

0

Hmm wypróbować ten kod i daj nam znać wyświetlamy

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

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

P.S: Może chcieć zmienić Typ klucza i wartości.

+0

thusChar spaceChar plusChar equalsIndent multiplyChar equalsChar newlineChar divideChar subjectChar variableIndent ∴ + # x = \ n ÷ : @ Dokładnie zgodnie z oczekiwaniami! Spróbuję z kluczem changd –

+1

Widzę 10 klawiszy i 9 wartości. – foklepoint

+0

Jednym z kluczy jest spacja. –

1

Jeśli obawiasz się problemów z kodowaniem (wydaje się, że jest to problem), upewnij się, że kodowanie Twojego projektu jest ustawione na UTF-8. Aby to sprawdzić, przejdź do menu Project i wybierz opcję Właściwości. Może to być konieczne, aby zmienić kodowanie pliku tekstowego z Inherited from container do Oher: UTF-8

+0

Gotowe. Wciąż nie ma sukcesu. Jestem absolutnie zaskoczony. –

+0

@Anti Earth Przypuszczam, że powinieneś wydrukować 'hashCode()' z "obu" Ciągów - this1 z mapy, i this1, które wyszukujesz i kończysz z niczym. Powinny być takie same, jeśli jest to ten sam String. – dantuch

+0

Odkrył to w innych odpowiedziach; nie są tym samym ciągiem znaków. Jakakolwiek linia z pliku tekstowego jest przetwarzana jako pierwsza i najpierw dodana do słownika, w jakiś sposób "mutuje" w ukryty sposób. Nadal nie wiem, jak i dlaczego. –

0

Jeśli uważasz, że to kwestia kodowania, a następnie spróbuj użyć następujących metod do porównania rzeczywistej zawartości, niezależnie od tego, jak to wygląda.

Zastosowanie getBytes() uzyskać wszystkie bajty z obu łańcuchów (klucz z mapy, a także ciąg w kodzie) oraz druk

  1. długości tablicy bajtów
  2. każdy bajt jako liczba całkowita

Następnie użyj getChars() aby wszystkie znaki z obu smyczki lub charAt() czytać każdy char i drukować

  1. Każdy znak jako liczbę całkowitą.

Pomiędzy tymi dwiema kontrolkami powinieneś być w stanie dowiedzieć się, jak oba ciągi są różne na poziomie bajtów. Jaki jest zestaw znaków, w którym zapisywany jest plik?

EDIT

Podejrzewam korzystanie z DataInputStream powoduje problemy z bajtów do odczytania.

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

Docs Java dla DataInputStream powiedzieć „Strumień danych wejściowych umożliwia aplikacja czytać prymitywnych typów danych Java z bazowego wejściowego strumienia w sposób maszynowo niezależne. Aplikacja wykorzystuje strumień wyjściowy danych do zapisu danych, które mogą później odczytany przez strumień danych wejściowych. " Nie czytasz z DataOutputStream tutaj, tylko zwykły plik. Ponadto, masz już InputStream dla InputStreamReader do użycia. Zmienić swój kod do tego:

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

EDIT 2

Inną rzeczą warto robić, skoro twój ciąg z pliku tekstowego jest 3 bajty dłużej, zmienia się to

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

do

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

Mam aktualizację problemu, która sprawia, że ​​myślę, że kodowanie może już nie być istotne: P –

+0

Czy możesz zaktualizować pytanie tym, co znalazłeś? –

+0

Oczywiście! (Przepraszam, jestem niesamowicie powolny na wszystko) –

0

Wypróbuj w ten sposób ...

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()); 


} 
Powiązane problemy