Create Custom Hashtable - java

I need to create a Custom Hashtable extends java.lang.Hashtable and i need to override the get method to achieve the following behavior :
if the key == null, it will return a new object of the type V
if the super.get(key) == null, it will also return a new object of type V.
Can anyone help me.
I try to do this but I know it's wrong.
import java.util.Hashtable;
public class CustomHashtable<K, V> extends Hashtable {
#Override
public synchronized V get(Object key) {
if(key == null) return new Object();
Object v = super.get(key);
if(v == null){
return new Object();
}
}
}
please see the line :
if(key == null) return new Object();
and the lines :
if(v == null){
return new Object();
}
to know where the error occurred..

You'd have to store the class related to V and create a new instance. For example:
public class CustomHashtable<K, V> extends Hashtable {
Class<V> clazz;
public CustomHashtable(Class<V> clazz) {
this.clazz = clazz;
}
#Override
public synchronized V get(Object key) {
if(key == null) return newValue();
Object v = super.get(key);
if(v == null){
return newValue();
}
}
private V newValue() {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException (e);
} catch (IllegalAccessException e) {
throw new RuntimeException (e);
}
}
}
(You may want to change the exception handling of course.)
An alternative is to make the caller effectively provide a factory to create a new instance of V. You'd do this with an interface such as:
public interface Factory<T> {
T create();
}
You could then store the factory in the custom hashtable, and call create any time you needed to.

The primary issue here is what you are trying to achieve is fundamentally wrongheaded. Checkout the methods of your class. The majority of them will now be inconsistent with get. Worse, exactly how methods are implemented in terms of other public methods is not defined - such is the curse of inheritance.
Therefore, create a class that represents whatever abstraction you are trying to achieve. Have the contain not inherit from an appropriate map implementation.
The natural map in this case is probably not ye olde Hashtable but java.util.concurrent.ConcurrentHashMap. The important method here is [putIfAbsent][2]. Unfortunately the API docs suck. Here is how it should be used:
public V getOrCreate(K key) {
final V value = map.get(key);
if (value != null) {
return value;
}
V newValue = factory.create(key); // May discard.
V oldValue = map.putIfAbsent(key, value);
return oldValue==null ? newValue : oldValue;
}
(You can use a Future if you want to ensure that you never discard a value.)
To create I've assumed some kind of an abstract factory. In general methods don't have no-args public constructors that happen not to throw exceptions. Certainly avoid reflection like swine flu crossed with H5N1. Instead use an appropriate (abstraction-specific) abstract factory passed in at creation time.
public interface MySortOfFactory<
T /*extends SomeEntity*/,
A /*extends SomeInfo*/
> {
T create(A arg);
}
[2]: http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentMap.html#putIfAbsent(K, V)

Do you need to create a new instance? or is it sufficient to return a default instance?
The latter could be implemented like:
public class CustomHashtable<K, V> extends Hashtable<K, V> {
/** Default instance. */
private final V defaultValue;
public CustomHashtable(V defaultValue) {
this.defaultValue= defaultValue;
}
#Override
public synchronized V get(Object key) {
if(key != null) {
V val = super.get(key);
if(val != null) {
return val;
}
}
return defaultValue;
}
}
(but I still prefer Jon's factory solution: more flexible and also covers the default instance solution)

I understand what you asked, but could I ask the following please:
Do you always want a new object when the key is null, or don't you just want to allow a null key?
Also, do you definitely need a new instance when you can't find the key, or will the same instance do in each case where you can't find the key?
Are you going to put the new instances into the Hashtable?
Does it have to be a Hashtable, or could a HashMap do?
I'm just wondering if you had considered using a LazyMap from Apache Commons Collections?

Related

How to check against generic enum in Java?

Here is my code:
public enum DecisionType {
REFUSAL,
GRANT_OF_PROTECTION,
PARTIAL_REFUSAL;
}
public class DocumentComposition<T extends Enum<DecisionType>> extends TreeMap<DocumentType, Object> {
#Override
public Object put(DocumentType key, Object value) {
if (key.getDecisionType() != ) {
return null;
}
return value;
}
}
DocumentComposition map = new DocumentComposition<DecisionType.REFUSAL>();
I need my Map to contain only elements that are of a certain value of the DecisionType enum. How do I achieve this? What should my test look like?
Do I understand it right you want to have a DocumentComposition which accepts only DocumentType instances of a specific DecisionType ?
My parts of the solution:
You don't need to use generics for that but rather an internal variable which you provide in the constructor.
In you overridden put method you must not forget to call the super otherwise your TreeMap will never get any elements.
public class DocumentComposition extends TreeMap<DocumentType, Object> {
private DecisionType acceptedDecisionType;
public DocumentComposition(DecisionType acceptedDecisionType)
{
this.acceptedDecisionType = acceptedDecisionType;
}
#Override
public Object put(DocumentType key, Object value) {
if (key.getDecisionType() != acceptedDecisionType) {
return null;
}
return super.put(key, value); // do not forget to call super, otherwise your TreeMap is not filled
}
}
Now you can use your map:
public static void main( String args[])
{
DocumentComposition dc=new DocumentComposition(DecisionType.REFUSAL);
dc.put(new DocumentType(DecisionType.REFUSAL), "refusalDoc");
dc.put(new DocumentType(DecisionType.PARTIAL_REFUSAL), "partialRefusalDoc");
System.out.println(dc);
}
Only refusalDoc will be in the map.

Ensuring thread safety for cache fetching values on its own

I built a generic cache that fetches values on miss by delegating to a ValueGenerator component. Internally, it has a map for values it has already obtained, and another map for in-flight requests so that they can be re-used across subscribers.
Here's the simplified code before I attempt to make it thread safe. My questions will follow.
public class NetworkCache<K, V> {
private final Map<K, V> mValues;
private final Map<K, Observable<V>> mRequests;
private final ValueGenerator<K, V> mValueGenerator;
public NetworkCache(ValueGenerator<K, V> valueGenerator) {
mValues = new HashMap<>();
mRequests = new HashMap<>();
mValueGenerator = valueGenerator;
}
public Observable<V> get(final K key) {
V value = mValues.get(key);
if (value != null) {
// We already had the value
return Observable.just(value);
}
Observable<V> requestObservable = mRequests.get(key);
if (requestObservable == null) {
// New request to fetch the value
requestObservable = mValueGenerator.generate(key);
// Store in-flight request for potential re-use
mRequests.put(key, requestObservable);
requestObservable.subscribe(new Subscriber<V>() {
#Override
public void onCompleted() { mRequests.remove(key); }
#Override
public void onError(Throwable e) { mRequests.remove(key); }
#Override
public void onNext(V value) { mValues.put(key, value); }
});
}
return requestObservable;
}
public interface ValueGenerator<K, V> {
Observable<V> generate(K key);
}
}
Now I'm trying to think how this could break under concurrency scenarios. I believe the focus should be on those two Map that are queried in get(), and modified in the subscribe callback.
I think it's reasonable to assume/enforce that this class can only be called on the main thread. The ValueGenerator, however, should be able to schedule its work on a different thread, as my use case is actually network requests.
I see 3 options, and I'd like help to figure out which one to use.
1. Use ConcurrentHashMap instead of HashMap
Constructor would change to:
public NetworkCache(ValueGenerator<K, V> valueGenerator) {
mValues = new ConcurrentHashMap<>();
mRequests = new ConcurrentHashMap<>();
mValueGenerator = valueGenerator;
}
With this approach, I don't know if it is sufficient and/or overkill.
2. Observe ValueGenerator call on main thread
To me, this means that all map operations would happen on the main thread (assuming that NetworkCache is only used there), even if the ValueGenerator used subscribeOn(Schedulers.io()). This would mean it is thread safe.
if (requestObservable == null) {
// New request to fetch the value
requestObservable = mValueGenerator
.generate(key)
.observeOn(AndroidSchedulers.mainThread());
...
3. Synchronize every access to the maps
I would keep using HashMap and the get method would become the following. Here, is synchronizing on the maps themselves the right approach? Do I need to block on every operation, or just put & remove?
public Observable<V> get(final K key) {
V value;
synchronized (mValues) {
value = mValues.get(key);
}
if (value != null) {
return Observable.just(value);
}
Observable<V> requestObservable;
synchronized (mRequests) {
requestObservable = mRequests.get(key);
}
if (requestObservable == null) {
requestObservable = mValueGenerator.generate(key);
synchronized (mRequests) {
mRequests.put(key, requestObservable);
}
requestObservable.subscribe(new Subscriber<V>() {
#Override
public void onCompleted() {
synchronized (mRequests) {
mRequests.remove(key);
}
}
#Override
public void onError(Throwable e) {
synchronized (mRequests) {
mRequests.remove(key);
}
}
#Override
public void onNext(V value) {
synchronized (mValues) {
mValues.put(key, value);
}
}
});
}
return requestObservable;
}
A little background on the utilization: the cache's get method would be called in rapid succession 1-10 times for different keys. That event would be infrequent, but could happen within a few seconds. It's when the second series of calls arrives, mixed with the observables from the first series coming back, that I worry about the execution.
I would do this with a single ConcurrentMap and AsyncSubject:
public class RequestCache<K, V> {
final ConcurrentMap<K, AsyncSubject<V>> values;
final Function<? super K, ? extends Observable<? extends V>> valueGenerator;
public RequestCache(
Function<? super K, ? extends Observable<? extends V>> valueGenerator) {
this.values = new ConcurrentHashMap<>();
this.valueGenerator = valueGenerator;
}
public Observable<V> get(K key) {
AsyncSubject<V> result = values.get(key);
if (result == null) {
result = AsyncSubject.create();
AsyncSubject<V> current = values.putIfAbsent(key, result);
if (current == null) {
Observable<? extends V> source = valueGenerator.apply(key);
source.subscribe(result);
} else {
result = current;
}
}
return result;
}
}
This is fully threadsafe and calls valueGenerator once per key only.
I think you should synchronize whole getter and setter functions.

Code for building generic chains of validations and transformations to an object

I am trying to write some general code to do the following. Given two kinds of "operations", (a) validation (eg. input: object & context -> output: boolean), and (b) transformation (eg. input: object_A, context -> output: object_B) -objects of any type-.
I want to be able to build chains of "operations", in which an input object and its context can be submitted through (eg. to validate and transform the object). Returning immediately if the object is "invalid" and being able to get the transformed object if it finished "valid".
Idea is that "validations" and "transformations" can be "plugable" functions that other people write and assemble in a chain (eg. they build chains and submit objects through them).
I managed to do the following code, which compiles and seems to work. However, I'm not an expert on generics and would like to hear feedback about possible pitfalls, enhancements, or even maybe some other better/easier approach to the problem. Thanks in advance.
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
interface Operation<T, U, V> {
U execute(T a, V context);
}
abstract class Validation<T, V> implements Operation<T, Boolean, V> {
#Override
public Boolean execute(T a, V context) {
return executeValidation(a, context);
}
public abstract Boolean executeValidation(T a, V context);
}
abstract class Transformation<T, U, V> implements Operation<T, U, V> {
#Override
public U execute(T a, V context) {
return executeTransformation(a, context);
}
public abstract U executeTransformation(T a, V context);
}
class OperationsChain {
List<Operation<Object, Object, Object>> operations = new ArrayList<Operation<Object, Object, Object>>();
Object currentObj;
public <T, V> Boolean run(T a, V context) {
Boolean valid = false;
currentObj = a;
for (Operation<Object, Object, Object> operation : operations) {
if (operation instanceof Validation) {
valid = (Boolean) operation.execute(currentObj, context);
} else if (operation instanceof Transformation) {
currentObj = operation.execute(currentObj, context);
}
if (!valid) {
break;
}
}
return valid;
}
#SuppressWarnings("unchecked")
public <T, U, V> void addOperation(Operation<T, U, V> operation) {
operations.add((Operation<Object, Object, Object>) operation);
}
public Object getCurrentObject() {
return currentObj;
}
}
class ValidationOne extends Validation<MapObject, Map<String, Object>> {
public Boolean executeValidation(MapObject a, Map<String, Object> context) {
if (context.containsKey("validation 1")) {
return (Boolean) context.get("validation 1");
} else {
return false;
}
}
}
class ValidationTwo extends Validation<MapObject, Map<String, Object>> {
public Boolean executeValidation(MapObject a, Map<String, Object> context) {
if (context.containsKey("validation 2")) {
return (Boolean) context.get("validation 2");
} else {
return false;
}
}
}
class TransformationOne extends Transformation<MapObject, MapObject, Map<String, Object>> {
public MapObject executeTransformation(MapObject a, Map<String, Object> context) {
if (context.containsKey("transformation 1")) {
a.addField("data", (String) context.get("transformation 1"));
}
return a;
}
}
class MapObject {
Map<String, String> fields = new HashMap<String, String>();
public void addField(String key, String value) {
fields.put(key, value);
}
public String getField(String key, String value) {
if (fields.containsKey(key)) {
return fields.get(key);
} else {
return null;
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : fields.entrySet()) {
sb.append(entry.getKey());
sb.append(": ");
sb.append(entry.getValue());
sb.append("\n");
}
return sb.toString();
}
}
class OperationsChainDriver {
public static void main(String[] args) {
OperationsChain oc = new OperationsChain();
oc.addOperation(new ValidationOne());
oc.addOperation(new TransformationOne());
oc.addOperation(new ValidationTwo());
oc.addOperation(new TransformationOne());
Map<String, Object> context = new HashMap<String, Object>();
context.put("validation 1", true);
context.put("validation 2", false);
context.put("transformation 1", "aloha");
MapObject mapObject = new MapObject();
mapObject.addField("field 1", "hello");
Boolean result = oc.run(mapObject, context);
if (result == true) {
System.out.println("valid\n"+oc.getCurrentObject().toString());
} else {
System.out.println("invalid\n"+oc.getCurrentObject().toString());
}
}
}
Generics are about type safety - not having to cast, because as you surely know casts are risks proved runtime. You have a very generic design yet get very concrete to and the like and have to cast a lot - this shouldn't happen since it defeats the reason to use generics at all.
As as side note: why not give an operation a method isValid that has always a return type of Boolean, a transformation can fail, too, so yo don't have to make a difference between validation and transformation. Or let it put a value in a context - the operation could know its context and could use it without casts. An operation chain could know its context and could get the results without casts.
Anyway - as long as you code has casts you are still not finished with it.
This kind of task is one that I think a functional language would be ideal for, e.g. Scala (which runs on the JVM and is perfect for interoperating with Java code), or Haskell (which doesn't run on the JVM, but has some other advantages).
OK, I understand if you don't want to learn a new programming language. But one of the key advantages would be that your code should be shorter and easier to read and reason about.

Does Java have a HashMap with reverse lookup?

I have data that is organized in kind of a "key-key" format, rather than "key-value". It's like a HashMap, but I will need O(1) lookup in both directions. Is there a name for this type of data structure, and is anything like this included in Java's standard libraries? (or maybe Apache Commons?)
I could write my own class that basically uses two mirrored Maps, but I'd rather not reinvent the wheel (if this already exists but I'm just not searching for the right term).
There is no such class in the Java API. The Apache Commons class you want is going to be one of the implementations of BidiMap.
As a mathematician, I would call this kind of structure a bijection.
In addition to Apache Commons, Guava also has a BiMap.
Here is a simple class I used to get this done (I did not want to have yet another third party dependency). It does not offer all features available in Maps but it is a good start.
public class BidirectionalMap<KeyType, ValueType>{
private Map<KeyType, ValueType> keyToValueMap = new ConcurrentHashMap<KeyType, ValueType>();
private Map<ValueType, KeyType> valueToKeyMap = new ConcurrentHashMap<ValueType, KeyType>();
synchronized public void put(KeyType key, ValueType value){
keyToValueMap.put(key, value);
valueToKeyMap.put(value, key);
}
synchronized public ValueType removeByKey(KeyType key){
ValueType removedValue = keyToValueMap.remove(key);
valueToKeyMap.remove(removedValue);
return removedValue;
}
synchronized public KeyType removeByValue(ValueType value){
KeyType removedKey = valueToKeyMap.remove(value);
keyToValueMap.remove(removedKey);
return removedKey;
}
public boolean containsKey(KeyType key){
return keyToValueMap.containsKey(key);
}
public boolean containsValue(ValueType value){
return keyToValueMap.containsValue(value);
}
public KeyType getKey(ValueType value){
return valueToKeyMap.get(value);
}
public ValueType get(KeyType key){
return keyToValueMap.get(key);
}
}
If no collisions occur, you can always add both directions to the same HashMap :-)
Here my 2 cents.
Or you can use a simple method with generics. Piece of cake.
public static <K,V> Map<V, K> invertMap(Map<K, V> toInvert) {
Map<V, K> result = new HashMap<V, K>();
for(K k: toInvert.keySet()){
result.put(toInvert.get(k), k);
}
return result;
}
Of course you must have a map with unique values. Otherwise, one of them will be replaced.
Inspired by GETah's answer I decided to write something similar by myself with some improvements:
The class is implementing the Map<K,V>-Interface
The bidirectionality is really guaranteed by taking care of it when changing a value by a put (at least I hope to guarantee it hereby)
Usage is just like a normal map, to get a reverse view on the mapping call getReverseView(). The content is not copied, only a view is returned.
I'm not sure this is totally fool-proof (actually, it's probably not), so feel free to comment if you notice any flaws and I'll update the answer.
public class BidirectionalMap<Key, Value> implements Map<Key, Value> {
private final Map<Key, Value> map;
private final Map<Value, Key> revMap;
public BidirectionalMap() {
this(16, 0.75f);
}
public BidirectionalMap(int initialCapacity) {
this(initialCapacity, 0.75f);
}
public BidirectionalMap(int initialCapacity, float loadFactor) {
this.map = new HashMap<>(initialCapacity, loadFactor);
this.revMap = new HashMap<>(initialCapacity, loadFactor);
}
private BidirectionalMap(Map<Key, Value> map, Map<Value, Key> reverseMap) {
this.map = map;
this.revMap = reverseMap;
}
#Override
public void clear() {
map.clear();
revMap.clear();
}
#Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
#Override
public boolean containsValue(Object value) {
return revMap.containsKey(value);
}
#Override
public Set<java.util.Map.Entry<Key, Value>> entrySet() {
return Collections.unmodifiableSet(map.entrySet());
}
#Override
public boolean isEmpty() {
return map.isEmpty();
}
#Override
public Set<Key> keySet() {
return Collections.unmodifiableSet(map.keySet());
}
#Override
public void putAll(Map<? extends Key, ? extends Value> m) {
m.entrySet().forEach(e -> put(e.getKey(), e.getValue()));
}
#Override
public int size() {
return map.size();
}
#Override
public Collection<Value> values() {
return Collections.unmodifiableCollection(map.values());
}
#Override
public Value get(Object key) {
return map.get(key);
}
#Override
public Value put(Key key, Value value) {
Value v = remove(key);
getReverseView().remove(value);
map.put(key, value);
revMap.put(value, key);
return v;
}
public Map<Value, Key> getReverseView() {
return new BidirectionalMap<>(revMap, map);
}
#Override
public Value remove(Object key) {
if (containsKey(key)) {
Value v = map.remove(key);
revMap.remove(v);
return v;
} else {
return null;
}
}
}
Quite an old question here, but if someone else has brain block like I just did and stumbles on this, hopefully this will help.
I too was looking for a bi-directional HashMap, sometimes it is the simplest of answers that are the most useful.
If you do not wish to re-invent the wheel and prefer not to add other libraries or projects to your project, how about a simple implementation of parallel arrays (or ArrayLists if your design demands it).
SomeType[] keys1 = new SomeType[NUM_PAIRS];
OtherType[] keys2 = new OtherType[NUM_PAIRS];
As soon as you know the index of 1 of the two keys you can easily request the other. So your lookup methods could looks something like:
SomeType getKey1(OtherType ot);
SomeType getKey1ByIndex(int key2Idx);
OtherType getKey2(SomeType st);
OtherType getKey2ByIndex(int key2Idx);
This is assuming you are using proper object oriented structures, where only methods are modifying these arrays/ArrayLists, it would be very simple to keep them parallel. Even easier for an ArrayList since you would not have to rebuild if the size of the arrays change, so long as you add/remove in tandem.

What is the best way to represent a composite key (key containing two values) of a Class and a Boolean

HashMap<Pair<Class<T>,Boolean>,String> abc = new HashMap<Pair<Class<T>,Boolean>,String>();
What is the best way to represent Pair here... Does Java offer anything?
My key will always be a {class,boolean} pair.
Thanks!
I'd create a new wrapper class and use that as the key
class CustomKey
{
String cls;
boolean booleanValue;
// override equals and hashcode
}
There isn't a Pair class in the Java library. There may be one in JDK7. Many large code bases end up with one.
However, are you sure a Pair is really what you want. A nicely encapsulated class with appropriate behaviour may be more appropriate. Both Boolean and Pair and notable for not having specific meaning.
If you really want efficiency, you might want to go for two IdentityHashMap<Class<T>,String>s.
FWIW, AFAIK, the closest to Pair<Class<T>,Boolean> in the Java library is java.util.concurrent.atomic.AtomicMarkableReference, but you'll need to extend it to override equals and hashCode
There is no class called Pair in Java; but there is the Map.Entry<K,V> interface, and there are two public implementations of it: AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry.
If you find it ugly to use nested classes directly in your code, you could always create a Pair class:
public class Pair<Type1, Type2> extends AbstractMap.SimpleEntry<Type1, Type2> {
public Pair(Type1 t1, Type2 t2) {
super(t1, t2);
}
}
Or you could write your own like this:
public final class Pair<Type1, Type2> {
public final Type1 first;
public final Type2 second;
public Pair(Type1 first, Type2 second) {
this.first = first;
this.second = second;
}
/**
* Factory method to ease the pain of generics.
*/
public static <T1, T2> Pair of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
#Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Pair other = (Pair) obj; // no generics needed here
if (this.first != other.first &&
(this.first == null || !this.first.equals(other.first)))
return false;
if (this.second != other.second &&
(this.second == null || !this.second.equals(other.second)))
return false;
return true;
}
#Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + (this.first != null ? this.first.hashCode() : 0);
hash = 37 * hash + (this.second != null ? this.second.hashCode() : 0);
return hash;
}
}
At this time Java does not have a Pair type or anything similar. I also did not find one in the Apache commons, although it is possible that I missed someting. In any case usually in this case a small immutable data class is created:
public class Key<T> {
private final Class<T> cls;
private final boolean flag;
public Key(Class<T> cls, boolean flag) {
this.cls = cls;
this.flag = flag; }
public Class<T> getClass() {
return cls; }
public boolean getFlag() {
return flag; }
// equals and hashCode *must* be implemented -- see Effective Java for examples
}
Some people in this case will use public final methods instead -- it is a matter of taste plus how likely the class will get more complicated.
I have seen a couple of Pair or Tuple classes implemented if there is a need for the class outside of a single case (or if the developers have a functional background).
I have two approaches here... create a key{class, Boolean} -> {string} or i could also do this.
{class} -> {Boolean, string}
the first approach has 1 level of indirection which the second approach has 2... what are the pros and cons here? Is the second approach bad?

Categories