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
Post a Comment