Need help using Java Generics

I am trying to create a system to respond to events that occur in my application, similar to the Observer pattern. In my system, EventProducertrigger events EventConsumerrespond to these events, and two are connected through a central hub:

For now, I will ignore EventProducerand focus on EventHuband EventConsumer:

interface EventConsumer<E extends Event> {
    void respondToEvent(E event);
}

class EventHub {
    private HashMap<Class</*event type*/>, HashSet<EventConsumer</*event type*/>>> subscriptions;
    public <E extends Event> void fireEvent(E event) {
        /* For every consumer in the set corresponding to the event type {
            consumer.respondToEvent(event);
        } */
    }
    public <E extends Event> void subscribeToEvent(EventConsumer<E> consumer) {
        /* Insert consumer into the set corresponding to E */
    }
}

The problem is the announcement HashMap: I want to be able to do something like

HashMap<Class<E extends Event>, HashSet<EventConsumer<E>>>
// or
<E extends Event> HashMap<Class<E>, HashSet<EventConsumer<E>>>

So, to EventConsumerbe parameterized with the same type Class, but the closest I can get

HashMap<Class<? extends Event>, HashSet<EventConsumer<? extends Event>>>

But then it would allow, for example, HashSet<EventConsumer<MouseClickEvent>>to Class<KeyPressEvent>be assigned , suggesting both KeyPressEvent, and a MouseClickEventsubclass Event.

subscribeToEvent: , , ,

subscriptions.get(E.class).put(consumer)

E .

? ?

+5
5

EventConsumer. Event EventConsumer.

interface EventConsumer {
    void respondToEvent(Event event);
}

class ClickEventConsumer implements EventConsumer {
   public void respondToEvent(Event event){
     ClickEvent ce = (ClickEvent)event;
     //...
   }
}

class EventHub {
  private HashMap<Class<? extends Event>, HashSet<EventConsumer>> subscriptions;

  public void fireEvent(Event event) {
    HashSet<EventConsumer> consumers = subscriptions.get(event.getClass());
    if (consumers != null){
      for (EventConsumer ec : consumers){
        ec.respondToEvent(event);
      }
    }
  }

  public void subscribeToEvent(Class<? extends Event> clazz, EventConsumer consumer) {
    HashSet<EventConsumer> consumers = subscriptions.get(clazz);
    if (consumers == null){
      consumers = new HashSet<EventConsumer>();
      subscriptions.put(clazz, consumers);
    }
    consumers.add(consumer);
  }
}
+1

, . - . - :

public class EventsMap<E extends Event> {
    HashMap<Class<E>, HashSet<E>> map;
}

- ty1824..

+2

, :

HashMap<Class<? extends Event>, Set<EventConsumer<? extends Event>>> subscriptions;

, :

<E extends Event> void addSubscription(Class<E> eventClass, EventConsumer<? super E> eventConsumer)

<E extends Event> Set<EventConsumer<? super E>> getSubscriptions(Class<E> eventClass)

, , API, , addSubscription, .

+1

EventHub? ?

interface EventConsumer<E extends Event> {
void respondToEvent(E event);
}

class EventHub<E extends Event> {
 private HashMap<Class<E>, HashSet<EventConsumer<E>>> subscriptions;

 public void fireEvent(E event) {
/*
 * For every consumer in the set corresponding to the event type {
 * consumer.respondToEvent(event); }
 */
  }

  public void subscribeToEvent(EventConsumer<E> consumer) {
  /* Insert consumer into the set corresponding to E */
}
}

E .

1: , , :

EventConsumer (-) EventType, /. EvenType - Enum. EventType.

0

, :

-, . :

static class A<E extends EventObject> {
}

static class B extends A<MouseEvent> {
}

public static void main(String[] args) {
    System.out.println(B.class.getGenericSuperclass());
}

B , .

, Type , .

, . . , , Class .

Secondly, Mapit cannot (well, as far as I know) be fixed with the help of generics. Of course, you can implement a type map, but I think there is one more interesting thing: when you fire up an event, you probably want to send it to everyone who has subscribed to this particular class of events, and to everyone who has subscribed to its parents. So it’s just event.getClass()going to be a little less than enough.

0
source

All Articles