Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: stewe 16. 04. 2011, 21:09:25
-
Zdravim,
mam takyto problem
public Config(HashMap<String, String> m) {
Set<String> hs1 = m.keySet();
this.keys = (String[]) hs1.toArray();
...
keySet() vrati Set<String>
toArray() vrati Object[] co pretypujem na String[] ale pritom pise ze:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at validation.Config.<init>(Config.java:26)
ked vyskusam druhu metodu "T[] toArray(T[] a)"
public Config(HashMap<String, String> m) {
Set<String> hs1 = m.keySet();
String[] pole = null;
this.keys = hs1.toArray(pole);
tak zasa vypise
Exception in thread "main" java.lang.NullPointerException
at java.util.AbstractCollection.toArray(AbstractCollection.java:176)
at validation.Config.<init>(Config.java:27)
co s tym?
dakujem za radu
-
Spravne:
String[] x = (String[]) hs1.toArray(new String[0]);
Ty mas (proto nullpointer)
String[] x = (String[]) hs1.toArray(null);
mrkni do manualu - viz http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collection.html#toArray(java.lang.Object[])
Obecne pretypovat z "vyssiho" (Object) na "nizsi" (String) objekt (v hierarchii) nejde.
-
Spravne:
String[] x = (String[]) hs1.toArray(new String[0]);
Len doplním, že máš 2 možnosti:
1) String[] x = hs1.toArray(new String[0]);
2) String[] x = (String[]) hs1.toArray();
V prvom prípade už nie je nutnosť pretypovávať.
-
spravil som to podla vasich rad a fici to
public Config(HashMap<String, String> m) {
Set<String> hs1 = m.keySet();
String[] k = hs1.toArray(new String[0]);
for (int i = 0; i < k.length; i++) {
if (configuration.containsKey(k[i])) {
configuration.remove(k[i]);
configuration.put(k[i], m.get(k[i]));
}
}
}
dakujem
-
Este jedna otazka - co presne si chcel tym kodom docielit? Mi pride trochu zbytocne komplikovany.
-
Chapem to tak, ze configuration je existujuca mapa nastaveni a cielom je naplnit ju z mapy v parametri a overridnut existujuce kluce.
Predovsetkym:
* cely ten kod sa da nahradit one-linerom, pretoze ak "configuration" je nejaky Map, tak
public Config(Map<String, String> keysAndValues) {
this.configuration.putAll(keysAndValues);
}
Metoda putAll() na java.util.Map prikazuje volat metodu put() a ta z definicie prepisuje existujuce kluce. Predoslu hodnotu pre dany kluc vrati v navratovej hodnote.
Dalsie poznamky
* pouzivat implementaciu v datovom type parametra je nepekne: lepsie je Map<String, String>. Moze sa totiz stat, ze mam nastavenia v TreeMape a v takej chvili je uz konstruktor Config-u pre mna nepouzitelny a musim lopatou prerubavat TreeMap na HashMap. V parametroch sa silne odporuca pouzivat interfejsy a nie implementacie.
* nazov parametra "m" je nepekne, to je zlozvyk zo stredoskolskeho Pascalu, kde sa premenne volaju m, pom1, pom2 a f.
* to prehadzovanie do pola a spat vobec nie je potrebne, vsak viem iterovat cez mnozinu for-each cyklom
for(String value : m.keySet()) {
....
}
-
ano princip si vystihol, robi to presne to, diky za putAll asi pouzijem to, parameter "m" je proste m ako mapa :D nic v tom nehladaj.
Dalsie poznamky
* pouzivat implementaciu v datovom type parametra je nepekne: lepsie je Map<String, String>. Moze sa totiz stat, ze mam nastavenia v TreeMape a v takej chvili je uz konstruktor Config-u pre mna nepouzitelny a musim lopatou prerubavat TreeMap na HashMap. V parametroch sa silne odporuca pouzivat interfejsy a nie implementacie.
ano to mas samozrejme pravdu ale ja viem ze to bude len ako hashmapa takze to proste neriesim ...
aneb, clovek sa stale uci :)
-
joj vobec sa mi ten moj sposob nepaci, idem to prekopat a zjednodusit ...
-
Pomenovanie parametrov ma svoj zmysel, lebo ked nahodou neexistuje / nie je po ruke JavaDoc, aspon z nazvov parametrov mozno odvodit ich zmysel. Rovnako autocomplete v IDE sa vie divat do nazvov parametrov a pomahat pri vyvoji.
Kratke identifikatory maju zmysel tak mozno v ulohe lokalnych premennych, alebo v ukazkach kodu (EntityManager em), ale ked mame Ctrl-Medzeru, tak rozdiel v pocte uderov je jeden az dva.
ano to mas samozrejme pravdu ale ja viem ze to bude len ako hashmapa takze to proste neriesim ...
Toto je uplne nestastne zmyslanie. Ty sice vies, ze to bude len hashmapa, ale buduci pouzivatel toho kodu moze pokojne mat data v inej mapovej strukture, ktora nemusi byt hashmapou. A ano, mozes povedat, ze ,,toto je zapoctak a nik iny to nepouzije", lenze taketo zlozvyky sa potom prenasaju aj do realneho kodu.
Ked tam das Map<String, String>, na tvojom klientskom kode sa nic nezmeni, kedze HashMap implements Map a trieda bude ovela flexibilnejsou.
To je presne vidiet na starom Swingu, kde na mnohych miestach v konstruktoroch veselo sedia Vectory. V casoch Javy 1.0 to bolo sice jedine mozne riesenia, ale po zavedeni Java Collection Frameworku je to cele na nic, lebo rozumny programator pouziva Listy a tak mu neostava nic ine, len zbytocne prebalovat new Vector(mojZoznam)).
-
dobre, bude tam Map, premenne pomenuvam (teda snazim sa) "normalne" a je mi jasne, ze ich nazov ma reflektovat to, k comu sluzia, tamto to bol len dokaz, ze "aha spravil som to principialne takto" ... tot vse
je tazke ten kod nebastlit ked "to je len pre teba" ... no bude to potom to lahsie ked to budes pisat s vedomim ze to je aj pre inych. tazko na cvicisku, lahko na bojisku :) musim sa naucit byt viac dosledny a disciplinovany.