Gautam Gautam - 4 months ago 12
Java Question

Subclassing HashBasedTable from guava collection

I have a multilevel map requirement and I am using Guava Table . More precisely HashBasedTable.

Since my code needs a lot of custom processing on this dataset I would like to implement a derived class e.g. EventActionRuleTable which holds a map of Event - Action objects against a source.

something like this

HashMap<Source , Map<Event, Action> ruleMap ;


I am replacing the above with a

Table<Source, Event , Action> ruleTable = HashBasedTable.create();


But to hold all my custom code I would like to subclass HashBasedTable and figured its simply not possible.

Thus I choose to go with a delegate i.e.

public EventActionRule extends Table<Source, Event, Action>{

private HashBasedTable<Source, Event, Action> backup = null ;

public HashBasedTable<Source, Event, Action> getBackupTable() {

if (backupTable == null) {
backupTable = HashBasedTable.create() ;
}

return backupTable;
}

@Override
public boolean isEmpty() {
return getBackupTable().isEmpty();
}

/**
All other methods of Table interface overridden to delegate calls to backup instance
*/
....
}



  1. Is this approach correct ? Can you list issues if its not ? Any alternative approach ?

  2. Is HashBasedTable Gwt serialization compatible ? I am asking since the two backup maps used internally in the HashBasedTable are annotated with @GwtTransient annotation.


Answer

Ad 1. Your approach is correct, although you can use built-in Guava solution for using delegates - Forwarding Decorators:

For all the various collection interfaces, Guava provides Forwarding abstract classes to simplify using the decorator pattern.

In your case, ForwardingTable is waiting for you:

public static class EventActionRule extends ForwardingTable<Source, Event, Action> {

    private Table<Source, Event, Action> delegate = HashBasedTable.create();

    @Override
    protected Table<Source, Event, Action> delegate() {
        return delegate;
    }

    // just an example: isEmpty (and other methods) is ready to be overriden
    @Override
    public boolean isEmpty() {
        boolean isEmpty = delegate().isEmpty();
        System.out.println("Was map empty? " + isEmpty);
        return isEmpty;
    }
}

Ad. 2. Yes, HashBasedTable is serializable under GWT.