Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-14 Tema obsahu Oto Buchta
Dne 14. dubna 2011 7:10 Martin Beránek martin.bera...@i.cz napsal(a):

 Tak sem na to asi došel, viz příklad v příloze. Ono to totiž takovou mapu
 zadefinovat pomocí generik vlastně nejde... nebo jde, ale její použití pak
 bude silně limitující.


Opět nic neočekávaného. Když si vytvořím mapu,
kde klíč je potomek, nemůžu přeci jako klíč použít předka.
To je princip generik,

Martin


 Dne 13.4.2011 07:44, Libor Jelinek napsal(a):

 Dobrý den!

 Studuju collection framework a mám k otázku rozhraní Map. To má uvedeno,
 že je to pár key-value K, V.

 /java.util
 Interface MapK,V
 Type Parameters:K - the type of keys maintained by this mapV - the type
 of mapped values/

 Proč tedy metoda jako *containsKey()* je deklarována jako
 *containsKey(Object key)* a nikoli *containsKey(K key)*?

 Dále např. proč je *V get(Object key)* a nikoli *V get(K key)*? Poč je
 *V remove(Object key)* a nikoli *V remove(K key)*?




-- 
Oto 'tapik' Buchta, ta...@buchtovi.cz, http://tapikuv.blogspot.com


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-14 Tema obsahu Miroslav Paulfranc
michal,ježek,1987-03-09 nebo případně jinou příslušnou formu by mohla vracet 
např. metoda toString;
pak už by bylo ale asi lepší vytvořit klíč jako samostatnou třídu; faktem ale 
asi je, že většinou je klíčem String nebo nějaký numerický typ


  Původní zpráva 
 Od: Oto Buchta ta...@buchtovi.cz
 Předmět: Re: Proč není genericita v metodách Map jako get(), remove()?
 Datum: 14.4.2011 00:45:00
 
 2011/4/13 Miroslav Paulfranc paul...@seznam.cz

  Dobrý den.
  Myslím si, že
 
  datumyNarozeni.get(p.getLogin());
 
  by nešlo použít, pokud by byl klíč složený z více položek.
  Pokud by objekt Person měl např. string name a string surname, nebo by
  došlo následně k dalšímu rozšíření - např. o rok narození, stačilo by myslím
  pouze náležitě změnit hash a equals a vše by pořád fungovalo.
 
 
 Pak ale nemohu přes michal vkládat do mapy. To bych musel použít třeba
 michal,ježek,1987-03-09
 a odpovídajícím způsobem naimplementovat ten equals() a hashCode(). Ale co
 když někdo zapomene,
 že se teď už musí používat datum narození a zadá jenom michal,ježek?


    Původní zpráva 
   Od: Ondřej Fafejta fafejta.ond...@gmail.com
   Předmět: Re: Proč není genericita v metodách Map jako get(), remove()?
   Datum: 13.4.2011 08:38:05
   
   2011/4/13 Martin Beránek martin.bera...@i.cz:
Zdravím,
   
našel jsem celkem rozumné vysvětlení:
   
Restrikce se zavádějí proto, aby se něco nepokazilo.
   
Zavoláním get s jiným typem se nic nepokazí. Ještě trošku umělý
  příklad:
   
MapString,Date datumyNarozeni = ...
class Person {
   String fullName
   String login
   
   hashCode {
   return login.hashCode();
   }
   
   equals(Object o) {
   return login.equals(o);
   }
}
   
datumyNarozeni.put(michal,new Date());
   
odnekud mi prijde objekt Person p kde je login michal, pak muzu udelat:
   
datumyNarozeni.get(p) a dostanu to spravne datum
   
Martin
   
  
   tak tento příklad se mi hodně nelíbí. Takového programátora zatahat za
  uši ;-)
   Nebudu koukat do implementace Person, jak je napsaný hashCode a equals
  ...
   Určitě by každý normální programátor napsal toto:
  
   datumyNarozeni.get(p.getLogin());
  
   V každém případě - původní dotaz je docela namístě.
   Úryvek ze stackoverflow mě úplně nepřesvědčil ...
   Kdyby člověk použil
   MapList, Something místo MapArrayList, Something, tak by to
   fungovalo i s ArrayList i s LinkedList.
  
   Fafi
  
  
  
 



 --
 Oto 'tapik' Buchta, ta...@buchtovi.cz, http://tapikuv.blogspot.com





Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-14 Tema obsahu Martin Beránek

Dne 14.4.2011 08:10, Oto Buchta napsal(a):

Dne 14. dubna 2011 7:10 Martin Beránek martin.bera...@i.cz
mailto:martin.bera...@i.cz napsal(a):

Tak sem na to asi došel, viz příklad v příloze. Ono to totiž takovou
mapu zadefinovat pomocí generik vlastně nejde... nebo jde, ale její
použití pak bude silně limitující.


Opět nic neočekávaného. Když si vytvořím mapu,
kde klíč je potomek, nemůžu přeci jako klíč použít předka.
To je princip generik,


Problém ale je, že jako klíč můžu použít jedině null, což je právě to 
limitující chování. Pokud se bavíme o metodě universlReadFromMap z 
mého příklad tak jediné co se přeloží je:


m.get(null);


Kdyby tedy Map,List,Set byly nadefinovány natvrdo s generiky, nešlo by 
psát _některé_ univerzální metody pro práci s nimi.


 Mám-li to dohnat do umělého extrému (nebudu testovat výsledek na
 null), tak jestli odchytnu NPE nebo ClassCast je vcelku jedno :-)

Tady jsem nepochopil co tím je myšleno. Prostě zadefinovat parametr get 
metody pomoci generika nam nic navic neprinasi (stav objektu se nijak 
pokazit nemuze) - pouze limituje při vytváření univerzálních algoritmů.


--
Martin Beránek
ICZ a.s., Pobočka Brno
http://www.i.cz



smime.p7s
Description: S/MIME Cryptographic Signature


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Josef Cacek
Ahojte,

2011/4/13 Libor Jelinek ljeli...@virtage.com:
 Studuju collection framework a mám k otázku rozhraní Map. To má uvedeno, že
 je to pár key-value K, V.
..
 Proč tedy metoda jako containsKey() je deklarována jako containsKey(Object
 key) a nikoli containsKey(K key)?
 Dále např. proč je V get(Object key) a nikoli V get(K key)? Poč je V
 remove(Object key) a nikoli V remove(K key)?

Copy/paste ze stackoverflow
(http://stackoverflow.com/questions/857420/what-are-the-reasons-why-map-getobject-key-is-not-fully-generic):
As mentioned by people above, the reason why get(), etc. is not
generic because the key of the entry you are retrieving does not have
to be the same type as the object that you pass in to get(); the
specification of the method only requires that they be equal. This
follows from how the equals() method takes in an Object as parameter,
not just the same type as the object.

Although it may be commonly true that many classes have equals()
defined so that its objects can only be equal to objects of its own
class, there are many places in Java where this is not the case. For
example, the specification for List.equals() says that two List
objects are equal if they are both Lists and have the same contents,
even if they are different implementations of List. So coming back to
the example in this question, according to the specification of the
method is possible to have a MapArrayList, Something and for me to
call get() with a LinkedList as argument, and it should retrieve the
key which is a list with the same contents. This would not be possible
if get() were generic and restricted its argument type.

 Díky
 Libor

-- pepa cacek


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Martin Beránek

Zdravím,

našel jsem celkem rozumné vysvětlení:

Restrikce se zavádějí proto, aby se něco nepokazilo.

Zavoláním get s jiným typem se nic nepokazí. Ještě trošku umělý příklad:

MapString,Date datumyNarozeni = ...
class Person {
String fullName
String login

hashCode {
return login.hashCode();
}

equals(Object o) {
return login.equals(o);
}
}

datumyNarozeni.put(michal,new Date());

odnekud mi prijde objekt Person p kde je login michal, pak muzu udelat:

datumyNarozeni.get(p) a dostanu to spravne datum

Martin

Dne 13.4.2011 07:44, Libor Jelinek napsal(a):

Dobrý den!
Studuju collection framework a mám k otázku rozhraní Map. To má uvedeno,
že je to pár key-value K, V.

/java.util
Interface MapK,V
Type Parameters:K - the type of keys maintained by this mapV - the type
of mapped values/

Proč tedy metoda jako *containsKey()* je deklarována jako
*containsKey(Object key)* a nikoli *containsKey(K key)*?

Dále např. proč je *V get(Object key)* a nikoli *V get(K key)*? Poč je
*V remove(Object key)* a nikoli *V remove(K key)*?

A to i v JDK7 - tedy dávno dávno po zavedení genericity. Možná to mi
něco nedochází jako začátečníkovi, ale pak mě to vrací k beztypovým
kolekcím z JDK4 a umožňuje pěkné čunárničky jako, že místo type error
dostanu jen null když jako jako klíč jasně označený v deklaraci jako
Integer můžu používat klidně String, Float, ale i ZipEntry - zkrátka
potomek Object, tedy cokoli:

import java.util.*;

public class MapPokus1 {
 public static void main(String[] args) {
 HashMapInteger, String psc = new HashMapInteger, String();
 psc.put(12000, Praha 1);
 psc.put(28101, Velim);

 System.out.println(psc.get(28101));// Velim
 System.out.println(psc.get(28101));// Velim
 System.out.println(psc.get(28101));// žádná chyba jen
null !!!
 System.out.println(psc.get(3.14));// žádná chyba jen
null !!!
 System.out.println(psc.get(new ZipEntry(soub.txt) ));
// žádná chyba jen null !!!
 }
}

Díky
Libor



--
Martin Beránek
ICZ a.s., Pobočka Brno



smime.p7s
Description: S/MIME Cryptographic Signature


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Ondřej Fafejta
2011/4/13 Martin Beránek martin.bera...@i.cz:
 Zdravím,

 našel jsem celkem rozumné vysvětlení:

 Restrikce se zavádějí proto, aby se něco nepokazilo.

 Zavoláním get s jiným typem se nic nepokazí. Ještě trošku umělý příklad:

 MapString,Date datumyNarozeni = ...
 class Person {
        String fullName
        String login

        hashCode {
                return login.hashCode();
        }

        equals(Object o) {
                return login.equals(o);
        }
 }

 datumyNarozeni.put(michal,new Date());

 odnekud mi prijde objekt Person p kde je login michal, pak muzu udelat:

 datumyNarozeni.get(p) a dostanu to spravne datum

 Martin


tak tento příklad se mi hodně nelíbí. Takového programátora zatahat za uši ;-)
Nebudu koukat do implementace Person, jak je napsaný hashCode a equals ...
Určitě by každý normální programátor napsal toto:

datumyNarozeni.get(p.getLogin());

V každém případě - původní dotaz je docela namístě.
Úryvek ze stackoverflow mě úplně nepřesvědčil ...
Kdyby člověk použil
MapList, Something místo MapArrayList, Something, tak by to
fungovalo i s ArrayList i s LinkedList.

Fafi


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Miroslav Paulfranc
Dobrý den.
Myslím si, že

datumyNarozeni.get(p.getLogin());

by nešlo použít, pokud by byl klíč složený z více položek.
Pokud by objekt Person měl např. string name a string surname, nebo by došlo 
následně k dalšímu rozšíření - např. o rok narození, stačilo by myslím pouze 
náležitě změnit hash a equals a vše by pořád fungovalo.



  Původní zpráva 
 Od: Ondřej Fafejta fafejta.ond...@gmail.com
 Předmět: Re: Proč není genericita v metodách Map jako get(), remove()?
 Datum: 13.4.2011 08:38:05
 
 2011/4/13 Martin Beránek martin.bera...@i.cz:
  Zdravím,
 
  našel jsem celkem rozumné vysvětlení:
 
  Restrikce se zavádějí proto, aby se něco nepokazilo.
 
  Zavoláním get s jiným typem se nic nepokazí. Ještě trošku umělý příklad:
 
  MapString,Date datumyNarozeni = ...
  class Person {
         String fullName
         String login
 
         hashCode {
                 return login.hashCode();
         }
 
         equals(Object o) {
                 return login.equals(o);
         }
  }
 
  datumyNarozeni.put(michal,new Date());
 
  odnekud mi prijde objekt Person p kde je login michal, pak muzu udelat:
 
  datumyNarozeni.get(p) a dostanu to spravne datum
 
  Martin
 

 tak tento příklad se mi hodně nelíbí. Takového programátora zatahat za uši ;-)
 Nebudu koukat do implementace Person, jak je napsaný hashCode a equals ...
 Určitě by každý normální programátor napsal toto:

 datumyNarozeni.get(p.getLogin());

 V každém případě - původní dotaz je docela namístě.
 Úryvek ze stackoverflow mě úplně nepřesvědčil ...
 Kdyby člověk použil
 MapList, Something místo MapArrayList, Something, tak by to
 fungovalo i s ArrayList i s LinkedList.

 Fafi





Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Oto Buchta
2011/4/13 Ondřej Fafejta fafejta.ond...@gmail.com

 2011/4/13 Martin Beránek martin.bera...@i.cz:
  Zdravím,
 
  našel jsem celkem rozumné vysvětlení:
 
  Restrikce se zavádějí proto, aby se něco nepokazilo.


Mám-li to dohnat do umělého extrému (nebudu testovat výsledek na null),
tak jestli odchytnu NPE nebo ClassCast je vcelku jedno :-)

V každém případě - původní dotaz je docela namístě.
 Úryvek ze stackoverflow mě úplně nepřesvědčil ...
 Kdyby člověk použil
 MapList, Something místo MapArrayList, Something, tak by to
 fungovalo i s ArrayList i s LinkedList.

 Fafi


Naprostý souhlas. Vkládat do mapy objekt s klíčem záměrně konkrétního typu
a vytahovat to jiným mi přijde, přinejmenším, podivné.

Ale co už, člověk se s tím naučí žít.
-- 
Oto 'tapik' Buchta, ta...@buchtovi.cz, http://tapikuv.blogspot.com


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Oto Buchta
2011/4/13 Miroslav Paulfranc paul...@seznam.cz

 Dobrý den.
 Myslím si, že

 datumyNarozeni.get(p.getLogin());

 by nešlo použít, pokud by byl klíč složený z více položek.
 Pokud by objekt Person měl např. string name a string surname, nebo by
 došlo následně k dalšímu rozšíření - např. o rok narození, stačilo by myslím
 pouze náležitě změnit hash a equals a vše by pořád fungovalo.


Pak ale nemohu přes michal vkládat do mapy. To bych musel použít třeba
michal,ježek,1987-03-09
a odpovídajícím způsobem naimplementovat ten equals() a hashCode(). Ale co
když někdo zapomene,
že se teď už musí používat datum narození a zadá jenom michal,ježek?


   Původní zpráva 
  Od: Ondřej Fafejta fafejta.ond...@gmail.com
  Předmět: Re: Proč není genericita v metodách Map jako get(), remove()?
  Datum: 13.4.2011 08:38:05
  
  2011/4/13 Martin Beránek martin.bera...@i.cz:
   Zdravím,
  
   našel jsem celkem rozumné vysvětlení:
  
   Restrikce se zavádějí proto, aby se něco nepokazilo.
  
   Zavoláním get s jiným typem se nic nepokazí. Ještě trošku umělý
 příklad:
  
   MapString,Date datumyNarozeni = ...
   class Person {
  String fullName
  String login
  
  hashCode {
  return login.hashCode();
  }
  
  equals(Object o) {
  return login.equals(o);
  }
   }
  
   datumyNarozeni.put(michal,new Date());
  
   odnekud mi prijde objekt Person p kde je login michal, pak muzu udelat:
  
   datumyNarozeni.get(p) a dostanu to spravne datum
  
   Martin
  
 
  tak tento příklad se mi hodně nelíbí. Takového programátora zatahat za
 uši ;-)
  Nebudu koukat do implementace Person, jak je napsaný hashCode a equals
 ...
  Určitě by každý normální programátor napsal toto:
 
  datumyNarozeni.get(p.getLogin());
 
  V každém případě - původní dotaz je docela namístě.
  Úryvek ze stackoverflow mě úplně nepřesvědčil ...
  Kdyby člověk použil
  MapList, Something místo MapArrayList, Something, tak by to
  fungovalo i s ArrayList i s LinkedList.
 
  Fafi
 
 
 




-- 
Oto 'tapik' Buchta, ta...@buchtovi.cz, http://tapikuv.blogspot.com


Re: Proč není genericita v metodách Map jako get(), remove()?

2011-04-13 Tema obsahu Martin Beránek
Tak sem na to asi došel, viz příklad v příloze. Ono to totiž takovou 
mapu zadefinovat pomocí generik vlastně nejde... nebo jde, ale její 
použití pak bude silně limitující.


Martin


Dne 13.4.2011 07:44, Libor Jelinek napsal(a):

Dobrý den!
Studuju collection framework a mám k otázku rozhraní Map. To má uvedeno,
že je to pár key-value K, V.

/java.util
Interface MapK,V
Type Parameters:K - the type of keys maintained by this mapV - the type
of mapped values/

Proč tedy metoda jako *containsKey()* je deklarována jako
*containsKey(Object key)* a nikoli *containsKey(K key)*?

Dále např. proč je *V get(Object key)* a nikoli *V get(K key)*? Poč je
*V remove(Object key)* a nikoli *V remove(K key)*?




--
Martin Beránek
ICZ a.s., Pobočka Brno
http://www.i.cz
public class Main {

	static class BadMapK, V {

		void put(K key, V value) {
		}

		V get(K key) {
			return null;
		}

	}

	static class Foo {}

	static class ExtFoo extends Foo {}

	public static void main(String[] args) {
		BadMapFoo, String map1 = new BadMapFoo, String();
		BadMapExtFoo, String map2 = new BadMapMain.ExtFoo, String();
		readFromMap(map1);
		readFromMap(map2); // ERROR
		universalReadFromMap(map1);
		universalReadFromMap(map2);
		;

	}

	public static void readFromMap(BadMapFoo, String m) {
		Foo f = new Foo();
		m.get(f);
	}

	public static void universalReadFromMap(BadMap? extends Foo, String m) {
		Foo f = new Foo();
		m.get(f); // ERROR
	}

}


smime.p7s
Description: S/MIME Cryptographic Signature


Proč není genericita v metodách Map jako get(), remove()?

2011-04-12 Tema obsahu Libor Jelinek
Dobrý den!
Studuju collection framework a mám k otázku rozhraní Map. To má uvedeno, že
je to pár key-value K, V.

*java.util
Interface MapK,V
Type Parameters:K - the type of keys maintained by this mapV - the type of
mapped values*

Proč tedy metoda jako *containsKey()* je deklarována jako *containsKey(Object
key)* a nikoli *containsKey(K key)*?

Dále např. proč je *V get(Object key)* a nikoli *V get(K key)*? Poč je *V
remove(Object key)* a nikoli *V remove(K key)*?

A to i v JDK7 - tedy dávno dávno po zavedení genericity. Možná to mi něco
nedochází jako začátečníkovi, ale pak mě to vrací k beztypovým kolekcím z
JDK4 a umožňuje pěkné čunárničky jako, že místo type error dostanu jen null
když jako jako klíč jasně označený v deklaraci jako Integer můžu používat
klidně String, Float, ale i ZipEntry - zkrátka potomek Object, tedy cokoli:

import java.util.*;

public class MapPokus1 {
public static void main(String[] args) {
HashMapInteger, String psc = new HashMapInteger, String();
psc.put(12000, Praha 1);
psc.put(28101, Velim);

System.out.println(psc.get(28101));// Velim
System.out.println(psc.get(28101));// Velim
System.out.println(psc.get(28101));// žádná chyba jen null !!!
System.out.println(psc.get(3.14));// žádná chyba jen null
!!!
System.out.println(psc.get(new ZipEntry(soub.txt) ));//
žádná chyba jen null !!!
}
}

Díky
Libor