Értékeket szeretnék hozzáadni egy HashMap fájlhoz, amelyet a metódusok a ugyanabba az osztályba. Két megoldásom van:

  1. Az összes érték hozzáadása static
  2. Amikor az első metódust meghívjuk, adjuk hozzá az

1. megoldás:

private static Map<Character, String> codes = new HashMap<>(); static { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

2. megoldás:

boolean methodIsCalled = false; public static char decode(String s) { if(!methodIsCalled) { addValues(); methodIsCalled = true; } // ... } private static void addValues() { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

Melyik a leghatékonyabb? Melyik a legjobb gyakorlat?

Megjegyzések

  • Miért teszi ezt egy HashMap-ba? Miért nem 26 karakterlánc tömb?
  • Hogyan oldja meg a 26 karakterlánc tömb ezt a problémát? Különösen, hogyan kell elvégezni a feltérképezést? Az A – > 0, B – > 0, … eredetű implicit konverzióra gondolsz?
  • @Ali egy végső tömb kezeli a változtathatatlanságot és az initalizációt. A- > 0, B- > 1 nagyon szépen elkerüli a szükséges egyéb könyvtárak számos egyéb kérdését, extra statikus blokkokat vagy építők. ' világos és ésszerű.
  • @MichaelT Talán ennél a konkrét példánál, tekintettel arra, hogy a felhasználó szeretné leképezni a morzekódot, egy tömb String a 26-os méretben rendben van, azonban ez nem általános megoldás. Válaszom egy általános megoldás felé irányult, nem pedig ez a konkrét. Sok esetben a domain akkora, hogy nem használhatunk közvetlen leképezést egész számokra, és hashmap-ot kell használnunk.
  • @MichaelT btw, egy tömb csak méretenként változtathatatlan, de változtathat egyik eleme. a [0] = " új val ".

Válasz

Az 1. megoldásod problémás lehet, mivel a hashmap statikus, és csak egyszer inicializálódik, és az osztályod összes példánya megosztja. Ez a szándékolt viselkedésed, vagy azt akarod, hogy minden példánynak legyen saját térképe? Ha csak egy térkép van, akkor azt javaslom, hogy statikus helyett adja át a halmazt a konstruktornak, például:

public class Data { private final Map<Character, String> codes; public Data(Map<Character, String> codes) { this.codes = codes} } 

A 2. megoldásod hozzáadódik a halmaz lusta kezdeményezésének költsége, valahányszor szükség van rá, és hozzáadja a program logikájához a csúnya ellenőrzést methodIsCalled. Szerintem a térkép inicializálása a konstruktorban jobb megoldás.

public class Data { private final Map<Character, String> codes; public Data() { this.codes = new HashMap<>(); codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); } } 

A másik kérdés, amire válaszolnia kell, az az, hogy ha később módosítja a hashmap értékeit vagy nem. Ha nem változtatja meg, akkor jobb, ha megváltoztathatatlan hashMaps-okat keres. Az egyik lehetőség a Collections.unmodifiableMap (térkép) használata.

Használhatja a Google Guava könyvtárakat is, amelyek lehetővé teszik a térkép inicializálását a egy sort és megváltoztathatatlan térképet kap:

ImmutableMap.<Character, String>builder() .put("A", ".-") .put("B", "-...") .put("C", "-.-.") .put("D", "-..") .put("E", ".") .put("F", "..-.") .build(); 

Válasz

Semmi nem verhető Guava ImmutableMap optimalizált memóriafelhasználásával, de itt van egy pár tiszta megoldás:

/* Name of the class has to be "Main" only if the class is public. */ class Ideone { private static final Map<Character, String> codes1; static { Map<Character, String> temp= new HashMap<Character, String>(); temp.put("A", ".-"); temp.put("B", "-..."); temp.put("C", "-.-."); temp.put("D", "-.."); temp.put("E", "."); temp.put("F", "..-."); // ... codes1 = Collections.unmodifiableMap(temp); } private static final Map<Character, String> codes2 = Collections.unmodifiableMap(new HashMap<Character, String>() { { put("A", ".-"); put("B", "-..."); put("C", "-.-."); put("D", "-.."); put("E", "."); put("F", "..-."); // ... } }); } 

Válasz

Ha nem ragaszkodik a lusta inicializáláshoz (és egy 26 elemből álló kicsi, nem növekvő térképhez nem kellene), akkor miért ne optimalizálna az olvashatóság érdekében? Mindig valami olyasmit használnék, hogy

private static Map<Character, String> codes = newMap( "A", ".-", "B", "-...", "C", "-.-.", ... ); 

(megfelelően definiált segítőfunkcióval newMap).

Megjegyzések

  • Írhat-e még newMap-ot is paramétercsomagokkal?
  • @ VF1 Megteheti, ha általános függvényként definiálja a varargokkal .

Válasz

Ezekben az esetekben feltételezem, hogy a kérdés nem a hatékony módszerről szól, hanem inkább arról, hogy mikor valóban szüksége van arra a térképre, amely inicializálva van, és készen áll.

statikus inicializálás esetén – az osztály betöltődésekor

a lusta betöltési módszerre szükség lehet, ha a „hatalmas” beállítást kell megadnia “térkép, és gyakran azt mondják, hogy ezek az értékek drága forrásból származnak (azaz a hálózaton keresztül), akkor is lehet, hogy nincs szükség külső zászlóra.

A Collection.isEmpty () megmondja, hogy ezt már inicializálták-e vagy sem (feltéve, hogy természetesen legalább egy értéket inicializálni lehetne)

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük