Dc0
Dc0

Reputation: 11

override getOrDefault of HashBiMap implementation

Working with Guava library. I want to override(to add some validation) the getOrDefault method of HashBiMap implementation. Looking into it, HashBiMap class is declared as final, I can't extend it. Any idea?

@GwtCompatible(emulated = true)
public final class HashBiMap<K, V> extends IteratorBasedAbstractMap<K, V>
    implements BiMap<K, V>, Serializable {
....
}

Upvotes: 0

Views: 152

Answers (1)

Olivier Gr&#233;goire
Olivier Gr&#233;goire

Reputation: 35467

Create a decorator around your HashBiMap to validate.

Guava popularized the Forwarding* helper classes concept to simplify the decorator pattern of most collection types.

By subclassing ForwardingXXX and implementing the delegate() method, you can override only selected methods in the targeted class, adding decorated functionality without having to delegate every method yourself.

But for some reason, the authors haven't provided us with a ForwardingBiMap yet. So I would create (a basic) one myself or wait for the issue about the missing ForwardingBiMap to be resolved. If you want to create your own, just do the following:

public abstract class ForwardingBiMap<K,V> implements BiMap<K,V> {

  protected abstract BiMap<K,V> delegate();

  // implement *all* other methods with the following pattern:
  // ReturnType method(ParamType param) {
  //   return delegate().method(param);
  // }

}

Then implement your validation:

public static <K,V> BiMap<K, V> validating(BiMap<K,V> delegate) {
  Objects.requireNonNull(delegate);
  return new ForwardingBiMap<K,V>() {

    @Override protected BiMap<K,V> delegate() { return delegate; }

    @Override public V getOrDefault(Object key, V defaultValue) {
      // Implement your own validation here
      return super.getOrDefault(key, defaultValue);
    }
  };
}

And then finally use it:

BiMap<String,String> backingBiMap = HashBiMap.create();
BiMap<String,String> validatingBiMap = ValidatingBiMap.validating(backingBiMap);
validatingBiMap.getOrDefault("Hello", "World");

Upvotes: 2

Related Questions