events - How to use generic collections with typed parameters in a generic map with wildcards (Java) -



events - How to use generic collections with typed parameters in a generic map with wildcards (Java) -

this question related how create , fire collection of consumers<t> in java event listener pattern. trying utilize collection of events help batch operations up, far can't seem come right configuration of generic definitions work.

here code far.

private concurrenthashmap<class<? extends event>, concurrentlinkedqueue<consumer<collection<? extends event>>>> listeners; public <t extends event> void listen(class<t> clazz, consumer<collection<t>> consumer){ concurrentlinkedqueue<consumer<collection<t>>> consumers = listeners.get(clazz); if (consumers == null) { consumers = new concurrentlinkedqueue<>(); listeners.put(clazz, consumers); // complains consumers not type collection<? extends event> } consumers.add(consumer); } public <t extends event> void fire(collection<t> eventtofire){ concurrentlinkedqueue<consumer<collection<? extends event>>> consumers = listeners.get(eventtofire.getclass()); if(consumers != null){ consumers.foreach(x -> x.accept(eventtofire)); } }

i've tried setting concurrentlinkedqueue<consumer<collection<t>>> consumers = listeners.get(clazz); concurrentlinkedqueue<consumer<collection<? extends event>>> consumers = listeners.get(clazz); complains consumers.add(consumer); not type consumer<collection<t>>.

no casting seems getting around this, exception of consumers.add((consumer<collection<? extends event>>)(object)consumer);, looks horrible me, , seems must missing something, or messing up, because doesn't seem should required step.

you want compiler know if key of type class<t> (where t extends event), value concurrentlinkedqueue<consumer<collection<t>>>.

unfortunately, there no way express fact. however, know it's true because key/value pairs ever set map have form. hence it's safe set in cast, include comment explaining why it's ok.

the type of values should

concurrentlinkedqueue<? extends consumer<? extends collection<? extends event>>>

not

concurrentlinkedqueue<consumer<collection<? extends event>>>

the latter queue of consumers must able take collection of any type extending event, want consumer accepts collections of some specific type t extending event. it's incredibly hard understand this, remember need ? extends @ every level when mix wildcards nested type parameters.

finally, eventtofire.getclass() isn't want returns class of collection type, whereas keys of type class<? extends event>. due type erasure, cannot type parameter collection @ runtime, need explicitly pass clazz fire well.

with these changes code becomes

private concurrenthashmap<class<? extends event>, concurrentlinkedqueue<? extends consumer<? extends collection<? extends event>>>> listeners; public <t extends event> void listen(class<t> clazz, consumer<collection<t>> consumer){ concurrentlinkedqueue<consumer<collection<t>>> consumers = (concurrentlinkedqueue<consumer<collection<t>>>) listeners.get(clazz); if (consumers == null) { consumers = new concurrentlinkedqueue<>(); listeners.put(clazz, consumers); } consumers.add(consumer); } public <t extends event> void fire(class<t> clazz, collection<t> eventtofire){ concurrentlinkedqueue<consumer<collection<t>>> consumers = (concurrentlinkedqueue<consumer<collection<t>>>) listeners.get(clazz); if(consumers != null){ consumers.foreach(x -> x.accept(eventtofire)); } }

the casts required in 2 lines assume key , value match, best can perchance do.

java events generics

Comments

Popular posts from this blog

java - How to set log4j.defaultInitOverride property to false in jboss server 6 -

c - GStreamer 1.0 1.4.5 RTSP Example Server sends 503 Service unavailable -

Using ajax with sonata admin list view pagination -