2009-04-03 7 views
7

Voglio avere un List o Array di qualche tipo, la memorizzazione di queste informazioni su ogni paese:modo migliore per conservare i codici Paese, nomi e continente in Java

  • 2 lettera codice
  • nome
  • Paese come il Brasile
  • continente/regione del mondo come l'Europa dell'est, America del Nord, ecc

io classificare ogni paese nella regione/continente manualmente (ma se esiste un modo per farlo automaticamente, fammelo sapere). Questa domanda riguarda come memorizzare e accedere ai paesi. Ad esempio, voglio essere in grado di recuperare tutti i paesi del Nord America.

Non voglio utilizzare file di testo locali o simili perché questo progetto verrà convertito in javascript utilizzando Google Web Toolkit. Ma archiviare in un Enum o in un altro file di risorse di qualche tipo, tenerlo separato dal resto del codice, è ciò che sono veramente dopo.

+1

Alcuni paesi appartengono a due continenti (in Europa, Turchia, Russia e Kazakistan), un rapporto M: N – mjn

+0

è il loro problema :). nessuno vorrà comunque utilizzare quei 3 paesi, e se lo fanno possono cercarli in ordine alfabetico anziché per regione –

+0

in modo da sapere quali paesi non saranno "usati"? devi essere un vero esperto ... – mjn

risposta

5

Ci sono 246 paesi in ISO 3166, si potrebbe ottenere un grande enum relè su questo. Preferisco utilizzare il file XML con l'elenco dei Paesi, puoi scaricarne uno da http://www.iso.org/ e caricarlo (ad es. Quando l'app è in fase di avvio). Quindi, poiché sono necessari in GWT, caricarli di nuovo come richiami RPC, ma ricordarsi di memorizzarli nella cache (una sorta di caricamento lento) in modo che non si finisca di caricarli ogni volta. Penso che sarebbe comunque meglio che tenerli in codice, dato che finirai con il caricamento dell'elenco completo ogni volta che si accede al modulo, anche se l'utente non avrà bisogno di usare questo elenco.

Quindi avete bisogno di qualcosa che terrà Paese:

public class Country 
{ 
    private final String name; 
    private final String code; 

    public Country(String name, String code) 
    { 
     this.name = name; 
     this.code = code; 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public String getCode() 
    { 
     return code; 
    } 

    public boolean equals(Object obj) 
    { 
     if (this == obj) 
     { 
      return true; 
     } 
     if (obj == null || getClass() != obj.getClass()) 
     { 
      return false; 
     } 

     Country country = (Country) obj; 

     return code.equals(country.code); 
    } 

    public int hashCode() 
    { 
     return code.hashCode(); 
    } 
} 

Per GWT questa classe avrebbe bisogno di implementare IsSerializable. E si può caricare chi, sul lato server utilizzando:

import java.util.ArrayList; 
import java.util.List; 
import java.io.InputStream; 

import org.dom4j.Attribute; 
import org.dom4j.Document; 
import org.dom4j.DocumentException; 
import org.dom4j.Element; 
import org.dom4j.io.SAXReader; 

public class CountriesService 
{ 
    private static final String EL_COUNTRY = "ISO_3166-1_Entry"; 
    private static final String EL_COUNTRY_NAME = "ISO_3166-1_Country_name"; 
    private static final String EL_COUNTRY_CODE = "ISO_3166-1_Alpha-2_Code_element"; 
    private List<Country> countries = new ArrayList<Country>(); 

    public CountriesService(InputStream countriesList) 
    { 
     parseCountriesList(countriesList); 
    } 

    public List<Country> getCountries() 
    { 
     return countries; 
    } 

    private void parseCountriesList(InputStream countriesList) 
    { 
     countries.clear(); 
     try 
     { 
      Document document = parse(countriesList); 
      Element root = document.getRootElement(); 
      //noinspection unchecked 
      Iterator<Element> i = root.elementIterator(EL_COUNTRY); 
      while (i.hasNext()) 
      { 
       Element countryElement = i.next(); 
       Element countryName = countryElement.element(EL_COUNTRY_NAME); 
       Element countryCode = countryElement.element(EL_COUNTRY_CODE); 

       String countryname = countryName.getText(); 
       countries.add(new Country(countryname, countryCode.getText())); 
      } 
     } 
     catch (DocumentException e) 
     { 
      log.error(e, "Cannot read countries list"); 
     } 
     catch (IOException e) 
     { 
      log.error(e, "Cannot read countries list"); 
     } 
    } 

    public static Document parse(InputStream inputStream) throws DocumentException 
    { 
     SAXReader reader = new SAXReader(); 
     return reader.read(inputStream); 
    } 
} 

Naturalmente, se avete bisogno di trovare paese Codice ISO del 2 lettera si potrebbe abituato a cambiare List per Mappa probabilmente. Se, come hai detto, hai bisogno di paesi separati per continente, potresti estendere XML da ISO 3166 e aggiungere i tuoi elementi. Basta controllare la loro licenza (sito Web ISO).

4

Se si ha spesso bisogno di fare una ricerca per continente, farei semplicemente una serie di elenchi immutabili, uno per ogni continente, e li popoliamo di conseguenza. L'elenco dei dati nazionali per un continente probabilmente non cambierà abbastanza frequentemente per il costo di ricostruzione di tale array da ricostruire quando qualcosa deve essere modificato.

Inoltre, se si desidera eseguire manualmente la classificazione del paese-continente, il resto è automatico e può essere eseguito a livello di programmazione.

+0

Cosa intendi con una lista immutabile? Puoi condividere qualche codice? Spiacente, sono un novizio di java –

+0

Un elenco immutabile è solo uno il cui contenuto non può essere modificato (vedi ReadOnlyCollection). Tuttavia, mi piace l'approccio di Michael meglio, e penso che dovresti prenderlo al posto mio. –

+0

Bene, possono essere combinati: enum Paese {... statico {per (Continente c: Continent.values ​​()) per (Paese cc: Paese.valori()) if (cc.getContinent() == c) byContinent.get (c) .add (cc)}/* convertito con Collections.immutableList() e immutableMap() */...} – Hugo

13

Basta fare un enum chiamato Paese. Le enumerazioni Java possono avere proprietà, quindi il codice e il nome del tuo paese. Per il continente, desideri pochissimo un altro enum.

public enum Continent 
{ 
    AFRICA, ANTARCTICA, ASIA, AUSTRALIA, EUROPE, NORTH_AMERICA, SOUTH_AMERICA 
} 

public enum Country 
{ 
    ALBANIA("AL", "Albania", Continent.EUROPE), 
    ANDORRA("AN", "Andorra", Continent.EUROPE), 
    ... 

    private String code; 
    private String name; 
    private Continent continent; 

    // get methods go here  

    private Country(String code, String name, Continent continent) 
    { 
     this.code = code; 
     this.name = name; 
     this.continent = continent; 
    } 
} 

Per quanto riguarda la memorizzazione e l'accesso, una mappa per ciascuno dei campi sarete cercando per, calettati su quel quel campo, sarebbe la soluzione standard. Poiché hai più valori per il continente, dovrai utilizzare un'implementazione di Map<?, List<Country>> o Multimap, ad es. dai commons di Apache.

+0

alcuni esempi di codice? –

+0

Africa: il continente perduto? – mjn

+0

Dovresti essere chiaro che stai memorizzando la versione "en-US" del "nome";) – Hugo

2

Il modo più semplice per farlo è quello di creare la struttura del paese/continente in Java utilizzando una mappa (o qualsiasi altra cosa di raccolta) e quindi persistono utilizzando XStream

Questo creerà una rappresentazione XML della collezione, e si può leggere molto facilmente nel tuo processo e convertirlo nuovamente nello stesso tipo di raccolta creato inizialmente. Inoltre, poiché è XML, puoi facilmente modificarlo al di fuori del codice. vale a dire solo in un editor di testo.

Vedere lo XStream tutorial per ulteriori informazioni.

0

utilizzando l'oggetto Locale è la soluzione migliore a cui riesca a pensare, non è necessario memorizzare nulla. Ma se stai usando GWT prova a farlo sul lato server, come alcuni dicono che non lo farai funzionare correttamente sul lato client (come viene tradotto in javascript) puoi inviarli al client in un RPC come dichiarato prima.

Problemi correlati