2012-06-01 40 views
9

Tôi đã gặp phải vấn đề tương tự với rất nhiều người dường như đối mặt với PHP, việc thiếu một giải pháp mảng kết hợp phong phú và dễ sử dụng. Tôi đã đọc các câu hỏi ở đây về cơ bản tất cả được đề xuất sử dụng HashMap, như thế này: Q: Java associative-arrayCác mảng kết hợp và Java

Tuy nhiên, tôi không nghĩ rằng các giải pháp được đề cập sẽ giải quyết được sự cố của tôi. Tôi sẽ giải thích.

Tôi có danh sách với 250 mục (quốc gia) mà tôi muốn lưu trữ dữ liệu. Dữ liệu có độ dài không xác định, nghĩa là dữ liệu có thể chứa nhiều mục nhập cho mỗi cột "", đôi khi không có mục nhập nào, đôi khi 4, v.v.

trong PHP tôi chỉ có thể làm điều này:

$country_data = new array(); 
$country_data["nl"]["currency"] = "euro"; 
$country_data["nl"]["languages"] = "Dutch"; 
... 
$country_data["us"]["currency"] = "US dollar"; 
$country_data["us"]["languages"] = array("English", "Spanish"); 

Vì vậy, đôi khi tôi muốn lưu trữ một mảng, đôi khi không. Ofcourse nó cũng có thể là một mảng với chỉ một mục thay vì một chuỗi, nhưng tôi chỉ nói.

Vì vậy, câu hỏi là, làm thế nào để lưu trữ và tìm nạp mảng trong mảng trong HashMap? Tôi hiểu rằng tôi khá mắc kẹt với giải pháp HashMap xấu xí, nhưng tôi vẫn không thể thấy cách điều này sẽ cho phép tôi lưu trữ các mảng, tôi chắc chắn rằng tôi đang nhìn một cái gì đó đơn giản. Một ví dụ dựa trên của tôi sẽ là tuyệt vời!

CẬP NHẬT

tôi đã lựa chọn để đi cho HashMaps của HashMaps Lý do cho điều này tôi cần để có thể giám sát tất cả mọi thứ một cách dễ dàng, và thay đổi một vài dòng giá trị khi cần thiết. Và điều này là linh hoạt, tôi có thể dễ dàng chỉ lấy tên quốc gia dựa trên mã quốc gia, ngôn ngữ hoặc tôi có thể lấy Hashata quốc gia khi tôi cần hoặc tất cả tên quốc gia, v.v.

public class iso_countries { 
    Map<String, Object> country_data  = new HashMap<String, Object>(); 
    Map<String, String> country_name  = new HashMap<String, String>(); 
    Map<String, String[]> country_idd  = new HashMap<String, String[]>(); 
    Map<String, String[]> country_cid  = new HashMap<String, String[]>(); 

    public iso_countries(){  
     country_name.put("nl",   "Netherlands");  
     country_idd.put("nl",  new String[]{"+31"}); 
     country_cid.put("nl",  new String[]{"#31#", "*31#"}); 
     setData(country_name, country_cid, country_idd); 
     // 249 * 4 lines more and later... 
    }//end method 

    public void setData(Map country_name, Map country_cid, Map country_idd){ 
     country_data.put("name", country_name); 
     country_data.put("idd", country_idd); 
     country_data.put("cid", country_cid); 
    }//end method 

    public String getCountryName(String countryCode){ 
     String name  = country_name.get(countryCode); 
     return name; 
    }//end method 

    public String[] getCountryIdd(String countryCode){ 
     String prefix[] = country_idd.get(countryCode); 
     return prefix; 
    }//end method 

    public String[] getCountryCid(String countryCode){ 
     String cid[] = country_cid.get(countryCode); 
     return cid; 
    }//end method 
}//end class 
+0

Bạn muốn hashmap như hành vi trong php hoặc bạn sẽ thực hiện mã trong java? –

+3

Tại sao danh sách của bạn có mã quốc gia và chỉ mục? Không phải '$ country_data [" us "]' hoạt động hoàn toàn ổn chứ? –

+1

chỉ để bình luận về mã PHP của bạn: nó thậm chí không thực hiện bất kỳ ý nghĩa, rằng các loại giá trị trong chỉ mục ''language'' có thể hoàn toàn khác nhau, một khi một chuỗi, một khi một mảng ... bạn nên quyết định bạn thích, và dính vào nó. Các kiểu trộn cho thấy một thực tế mã hóa thực sự xấu, nó làm cho mã của bạn thất thường. EDIT: @Brendan Long: có, đó là một thông báo tốt quá. – Sk8erPeter

Trả lời

8

Bạn có thể lưu trữ các mảng như giá trị của một HashMap:

HashMap<Integer,String[]> hm = new HashMap<Integer,String[]>(); 
hm.put(1, new String[]{ "a", "b" }); 

Đối với là có "đa chiều" chìa khóa, bạn luôn có thể bọc chúng lại với nhau với một lớp. Một, mặc dù xấu xí, giải pháp sẽ là có HashMap s trong số HashMap s.

+1

Nếu phím của bạn là số nguyên liên tiếp, tại sao không sử dụng mảng hoặc danh sách thay vì bản đồ? –

+0

cảm ơn, tôi đã chọn giải pháp này làm giải pháp của mình. Tôi thực sự đã chọn giải pháp xấu xí và đang sử dụng HashMaps của HashMaps. Tôi sẽ gửi mã của tôi sau và giải thích. – slinden77

12

Có thể tôi hiểu nhầm vấn đề của bạn, nhưng tại sao không tạo đối tượng của riêng bạn để giữ dữ liệu, sau đó lưu trữ đối tượng đó trong HashMap?

Java là ngôn ngữ hướng đối tượng, vậy tại sao không sử dụng cơ sở nổi tiếng nhất của nó: các đối tượng!

+4

Có thể bởi vì sau nhiều năm kinh nghiệm Java bạn có thể học PHP và tìm ra rằng các mảng kết hợp là các đối tượng bạn đã từng tìm kiếm. Chúng dễ làm mát hơn nhiều, bởi vì bạn chỉ cần điền chúng vào cơ sở dữ liệu và truy cập chúng ngay trong GUI của bạn. Không cần mô hình dữ liệu Java, vì vậy ít nhất 20% làm việc ít nhất. Bạn thay đổi cơ sở dữ liệu lỗ của bạn? Không có vấn đề gì, GUI Java cũ của bạn vẫn chạy nếu nó sử dụng các mảng kết hợp. Bạn chỉ cần điền vào cùng một mảng từ cơ sở dữ liệu mới. Cuối cùng, nó tạo ra các mảng bản đồ băm thay vì bản đồ băm của các đối tượng như bạn đã đề xuất. Lập trình là một nghệ thuật. ;) – Marcus

+0

có, nó chỉ là một công việc toàn bộ nhiều hơn để đạt được một cái gì đó đơn giản như vậy – slinden77

+0

@ Marcus đó là một quan sát tốt. Đã không nghĩ về điều đó trước đây. – kevin628

11

Mảng trong PHP thực sự là băm chứ không phải mảng.

Điều chính xác để sử dụng trong java là HashMap. Bạn cũng có thể lưu trữ các giá trị multpile trong Hashmap bằng cách lưu trữ mảng hoặc danh sách trong đó. Vì vậy, HashMap<String, HashMap<String, Object> hoặc Hashmap<String, List<Object>> có thể giúp bạn.

Khi bạn sử dụng mảng đa chiều, bạn phải sử dụng số nguyên làm khóa.

2

bây giờ thay vì mảng bạn đặt danh sách, trong trường hợp bình thường bạn sẽ chỉ đặt chuỗi làm giá trị.

Một cách tiếp cận khác sẽ là sử dụng đối tượng giá trị lưu trữ bất kỳ thứ gì bạn đã cung cấp cho nó.

public class ValueObject { 

    private Map<String, List<Object>> dataHolder = null; //getter, setter 
} 

Map<String, ValueObject> map = new HashMap<String, ValueObject>(); 
5

Cách đúng là sử dụng một đối tượng Quốc gia:

class Country { 
    // Might want these private with getters and/or setters 
    public String currency; 
    public Set<String> languages; 

    // String...languages is like String[] languages, except you can pass the 
    // arguments in like new Country("Euro", "Dutch", "German") 
    // instead of new Country("Euro", new String[] { "Dutch", "German" }) 
    // It's purely stylistic 
    public Country(String currency, String... languages) { 
     this.currency = currency; 
     this.languages = new HashSet<String>(); 
     for(String language : languages) { 
      this.languages.add(language); 
     } 
     // or this.languages = new HashSet<String>(Arrays.asList(languages)); 
    } 
} 

void someFunction() { 
    Map<String, Country> countries = new HashMap<String, Country>(): 
    countries.put("us", new Country("US Dollar", "English", "Spanish")); 
    countries.put("nl", new Country("Euro", "Dutch")); 
} 

Bạn có thể làm điều này bằng cách làm tổ Lists và Maps, bởi lý do tại sao sử dụng Java nếu bạn đang không sử dụng các công cụ trình biên dịch cung cấp cho bạn?

+1

Đây là ý tưởng đúng. Tôi muốn đề nghị trường thành viên 'ngôn ngữ' là 'Đặt ' hoặc 'Danh sách ' thay vì một mảng. Trong hàm khởi dựng, người ta có thể lặp qua các ngôn ngữ arg để thêm chúng vào tập hợp một lúc hoặc sử dụng 'Arrays.toList()'. –

1

Ngoài ra, nếu thông tin của bạn về nước, tiền tệ và các ngôn ngữ có thể được xác định tĩnh, bạn có thể đặt tất cả những gì trong một bộ đếm:

public enum Language { 
    EN, ES, FR; 
} 

public enum Currency { 
    USD, GBP, CAD; 
} 

public enum Country { 

    US(USD, EN), UK(GBP, EN), CAN(CAD, EN, FR); 

    private final Language[] languages; 
    private final Currency currency; 

    Country(Currency currency, Language... languages) { 
     this.currency = currency; 
     this.languages = Arrays.copyOf(languages, languages.length); 
    } 

    public Currency getCurrency() { 
     return this.currency; 
    } 

    public Collection<Language> getLanguages() { 
     return asList(this.languages); 
    } 
} 

Sau đó, bạn có thể rất dễ dàng làm điều gì đó như:

Map<Integer, Country> data = new HashMap<Integer, Country>(); 
data.put(0, US); 
data.put(1, UK); 

Currency currency = data.get(0).getCurrency(); 
Collection<Language> langs = data.get(0).getLanguages(); 

System.out.println(currency); 
System.out.println(langs); 
Các vấn đề liên quan