java - Map from T to T -


say want use map , have following requirement: want each key map value of same type.

map<???> map = ...; map.put(42, 15); map.put("hello world", 15); // compile time error, because cannot map string int. map.put("hello world", "foobar"); map.put(new foo(), new foo()); integer = map.get(42); string s = map.get("hello world"); foo f = map.get(new foo()); 

of course above code not compile trick map t t t not defined @ instantiation. map returns same type parameter. of course made more fun, mapping t list<t>. without ugly casting?

scala's type system considered more advanced, there solution in scala?

if answer both of above questions no, there language supports such typing?

note: map in above code example of type takes 2 generic parameters. i'm not interested in map in particular, more in type system.

it's not precisely you're describing, well-known pattern in java typesafe heterogeneous container (effective java item 29), maps class<t> instance of t. guava provides classtoinstancemap interface implements pattern.


in java, can jury-rig type describing, won't pretty.

public class ttmap extends forwardingmap<object, object> {   private final hashmap<object, object> delegate = new hashmap<>();   @override   protected map<object, object> delegate() {     return delegate();   }    @suppresswarnings("unchecked")   public <t> t gettype(t key) {     return (t)delegate().get(key);   }    @suppresswarnings("unchecked")   public <t> t puttype(t key, t value) {     return (t)delegate().put(key, value);   }    @override @deprecated   public object put(object key, object value) {     preconditions.checkstate(key == value || value.getclass().equals(key.getclass()));     return delegate.put(key, value);   }    @override @deprecated   public void putall(map<? extends object, ? extends object> map) {     standardputall(map);   } } 

this uses forwardingmap give map<object, object> runtime constraint keys , values of same type. need use gettype() , puttype() avoid risk of runtime errors; put() , putall() can enforce constraint runtime exceptions. add putall(ttmap) method, if wanted.

the key == value check in put() allows nulls long both key , value null. if 1 or other is, you'll nullpointerexception @ class equality check.

also note @radiodef's comment - every type extends object, there's no way - generics - prevent 2 types being cast object , inserted. you'll need additional runtime checks address that.

if implementing map isn't requirement, follow similar pattern (a private map<object, object> , typed getters , setters) on new class easily.


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -