2012-08-11 42 views
5

Tôi đang gặp một vấn đề rất khác thường.
Về cơ bản, tôi đang cố gắng lấy giá trị được liên kết với một khóa từ một Bản đồ các chuỗi thành các chuỗi.
Tôi biết rằng khóa tôi đang sử dụng hiện diện; Tôi đang sử dụng cùng một chuỗi tôi đã sử dụng để đặt nó vào!Bản đồ Java trả về giá trị rỗng cho một khóa hiện tại

Tôi đã báo cáo in trên tất cả các mã của tôi, và đây là trường hợp tôi có ...
Đây là từ điển của tôi characterDictionary

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

Mấu chốt cuối cùng "variableIndent" là rắc rối!
Dưới đây là các mã ...

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

mà không thích hợp kết quả đầu ra: null

Tôi đã kiểm tra, hai lần kiểm tra và ba kiểm tra mã của tôi.
Hoàn toàn không có sự khác biệt giữa khóa "biếnIndent" và đối số chuỗi của characterDictionary.get("variableIndent"), nhưng nó hoạt động như thể phím này không có mặt.

Tôi hoàn toàn có thể đảm bảo khóa này có mặt và hai chuỗi giống hệt nhau.
Tất cả các yếu tố khác (những yếu tố tôi đã kiểm tra; khoảng 3 từ trước đến nay) của từ điển được truy xuất như bình thường. Tại sao "variableIndent" với giá trị "@" đang phát?

Bạn có thể nhận thấy từ điển chứa các ký tự không phải ASCII, như "thusChar". Điều này có thể liên quan?

Cảm ơn
(Điều này có vẻ như một vấn đề rất đơn giản và tầm thường, như thể tôi đã thực hiện một số sai lầm đáng thương ngớ ngẩn, nhưng nhưng tôi chỉ không thể giải quyết nó!)

EDIT:

Được rồi, đây là một điều gì đó về mã hóa.
Tôi lấy khóa chuỗi từ từ điển và so sánh nó với đối số nhận được của tôi.
Khi in, chúng giống hệt nhau, nhưng java nói rằng chúng không bằng nhau.
Chuỗi khóa đến từ một tệp văn bản được mã hóa UTF-8, trong khi chuỗi đối số đến từ một chữ java Eclipse.
Tuy nhiên, các ký tự giống hệt nhau.
Sự cố là gì và cách tôi có thể giải quyết vấn đề này?

Cảm ơn!

EDIT:

Hmmm, đây là những gì thực sự xảy ra đằng sau hậu trường.
Tôi có tệp văn bản UTF-8 có chứa nội dung sau ...

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

tôi 'tải' tập tin này bằng cách đọc trong mỗi dòng của tập tin như một yếu tố ArrayList<String>, bằng cách thông qua các thư mục của tập tin:

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

Mọi thứ đều tốt lên đến đây.
Sau đó, tôi chuyển ArrayList này vào một hàm tách từng phần tử bằng ký tự "," (sử dụng hàm từ gói cá nhân; Nó chắc chắn không phải là vấn đề) và thêm phần đầu tiên làm khóa cho phần tử thứ hai từ điển mới.

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

và điều này tạo ra từ điển gây ra tất cả sự cố.
Tôi có một bộ Key Literals tương ứng với tên ký tự trong các tệp văn bản mà tôi sử dụng để truy cập từ điển trong chương trình.

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

đây là vấn đề:

Dòng trên cùng của 'vít lên' textfile trong từ điển. Nó được thêm vào từ điển và xuất hiện chính xác giữa các keySet và định dạng in của từ điển, nhưng cố gắng truy cập nó trả về "null".
(Trong trường hợp này, đó là biếnIndent. Nếu tôi đặt biếnIndIndent ở một nơi khác trong tệp văn bản, bằng ốc vít Hiện tại lên, v.v.)

Điều gì đang xảy ra !?
Tôi có chức năng tinh nghịch không ?!
Họ đã làm việc tốt cho mọi thứ khác.

Cảm ơn!

+0

Để đảm bảo khóa này hiện diện, hãy lặp lại tất cả các phím trong bản đồ này và in giá trị của chúng. –

+0

Bạn có thể cho thấy một số tái tạo hành vi không? – assylias

+0

đã chỉnh sửa OP. Tin rằng nó là một vấn đề mã hóa giữa một textfile và Eclipse. –

Trả lời

6

thay đổi tệp văn bản UTF-8 có chứa khóa và giá trị thành UTF-8 không có BOM. Có ba byte (UTF-8 BOM 0xEF, 0xBB, 0xBF trước "biếnIndent") xem http://en.wikipedia.org/wiki/Byte_order_mark

+0

Làm cách nào để tôi thực hiện điều đó? –

+1

bạn có thể sử dụng ultraedit hoặc notepad ++ – andy

+0

@AntiEarth Điều này có thể giúp ... Dù sao, nếu bạn tìm giải pháp, vui lòng thông báo cho tôi. Tôi tò mò làm thế nào bạn sẽ giải quyết vấn đề kỳ lạ như vậy. Đáng buồn thay không có cách nào tự động để bỏ rơi các câu hỏi trên SO. – dantuch

0

Tôi khuyên bạn nên xem mã của mình trong trình gỡ lỗi. Tôi nghi ngờ bản đồ không phải là những gì bạn nghĩ.

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

in

variableIndent is @ 

bạn có thể thử

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

in các keyset và nhận '[thusChar, spaceChar, plusChar, equalsIndent, multiplyChar, equalsChar, newlineChar, divideChar, subjectChar, variableIndent]' –

0

Hmm thử mã này và cho chúng tôi biết sản lượng

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

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

P.S: Có thể muốn thay đổi Loại khóa và giá trị.

+0

thusChar spaceChar plusChar equalsIndent multiplyChar equalsChar newlineChar divideChar subjectChar variableIndent ∴ + # × = \ n ÷ : @ Chính xác như mong đợi! Tôi sẽ thử với phím thay đổi –

+1

Tôi thấy 10 khóa và 9 giá trị. – foklepoint

+0

Một trong những chìa khóa là một không gian. –

1

Nếu bạn sợ vấn đề mã hóa (có vẻ như là vấn đề ở đây), bạn phải đảm bảo mã hóa dự án của bạn được đặt thành UTF-8. Để kiểm tra, hãy truy cập vào menu Dự án và chọn Thuộc tính. Nó có thể được yêu cầu để thay đổi tập tin mã hóa văn bảnInherited from container-Oher: UTF-8

+0

Xong. Vẫn không thành công. Tôi hoàn toàn bối rối. –

+0

@Anti Earth Tôi cho rằng bạn nên in 'hashCode()' của "cả hai" Strings - this1 từ bản đồ và this1 mà bạn tìm kiếm và kết thúc bằng không có gì. Chúng phải giống nhau, nếu nó là cùng một chuỗi. – dantuch

+0

Khám phá điều này trong các câu trả lời khác; chúng không phải là cùng một chuỗi. Cho dù dòng nào từ tệp văn bản được xử lý trước tiên và được thêm vào từ điển trước, bằng cách nào đó 'biến đổi' theo cách ẩn. Vẫn không biết làm thế nào hoặc tại sao. –

0

Nếu bạn nghĩ rằng đó là một vấn đề mã hóa, sau đó hãy thử sử dụng các phương pháp sau đây để so sánh nội dung thực tế, không phụ thuộc vào những gì nó trông như thế nào.

Sử dụng getBytes() để có được tất cả các byte từ cả hai Strings (chìa khóa từ bản đồ, cũng như các chuỗi trong mã của bạn), và in

  1. Chiều dài của mảng byte
  2. Mỗi byte là một số nguyên

Sau đó sử dụng getChars() để có được tất cả các ký tự từ cả hai Strings hoặc charAt() để đọc mỗi char, và in

  1. Mỗi char làm số nguyên.

Giữa hai lần kiểm tra này, bạn sẽ có thể tìm ra cách cả hai chuỗi khác nhau ở mức byte. Bộ ký tự mà tập tin được lưu là gì?

EDIT

tôi nghi ngờ việc bạn sử dụng DataInputStream đang gây ra vấn đề với các byte được đọc.

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

Các tài liệu Java cho DataInputStream nói "Một dòng dữ liệu đầu vào cho phép một ứng dụng đọc nguyên thủy kiểu dữ liệu Java từ một input stream cơ bản theo một cách máy độc lập. Một ứng dụng sử dụng một output stream dữ liệu để ghi dữ liệu đó có thể sau đó được đọc bởi luồng đầu vào dữ liệu. " Bạn không đọc từ một DataOutputStream ở đây, chỉ là một tệp thông thường. Ngoài ra, bạn đã có InputStream cho InputStreamReader để sử dụng. Thay đổi mã của bạn như thế này:

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

EDIT 2

Một điều đáng làm, vì chuỗi của bạn từ các tập tin văn bản là 3 byte còn, đang thay đổi này

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

để

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

Tôi đã cập nhật sự cố khiến tôi nghĩ rằng mã hóa có thể không còn liên quan nữa: P –

+0

Bạn có thể cập nhật câu hỏi bằng những gì bạn đã tìm thấy không? –

+0

Chắc chắn! (Xin lỗi, tôi đặc biệt chậm chạp ở mọi thứ) –

0

Hãy thử theo cách này ...

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


} 
Các vấn đề liên quan