import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* This class <code>TwoWayMap</code> is useful for some utility that is not present in map.Its custom Map Class. It has
* two constructor default and parameterized.
*
* @see @link {@link #TwoWayMap()}
* @link {@link #TwoWayMap(K,V)}
*
* @author vishal.lakhmapurkar Date - 29-JUL-2012 : 1:04 AM
* @version 1.0
*
*
*
* @param <K>
* generic type key you can pass.
* @param <V>
* generic type key you can pass.
*/
public class TwoWayMap<K, V> {
static class DuplicationKeyException extends Exception {
public static final long serialVersionUID = 289373261293190L;
public DuplicationKeyException() {
super();
}
public DuplicationKeyException(final String message) {
super(message);
}
public DuplicationKeyException(final String message, final Exception cause) {
super(message, cause);
}
public DuplicationKeyException(final Throwable cause) {
super(cause);
}
}
static class DuplicationValueException extends Exception {
public static final long serialVersionUID = 289373261203190L;
public DuplicationValueException() {
super();
}
public DuplicationValueException(final String message) {
super(message);
}
public DuplicationValueException(final String message, final Exception cause) {
super(message, cause);
}
public DuplicationValueException(final Throwable cause) {
super(cause);
}
}
private static Map sortKeyByComparator(final Map unsortMap) {
if (unsortMap.containsKey(null)) {
unsortMap.remove(null);
}
List list = new LinkedList(unsortMap.entrySet());
// sort list based on comparator
Collections.sort(list, new Comparator() {
@Override
public int compare(final Object o1, final Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getKey()).compareTo(((Map.Entry) (o2)).getKey());
}
});
// put sorted list into map again
Map sortedMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
private static Map sortValueByComparator(final Map unsortMap) {
if (unsortMap.containsKey(null)) {
unsortMap.remove(null);
}
List list = new LinkedList(unsortMap.entrySet());
// sort list based on comparator
Collections.sort(list, new Comparator() {
@Override
public int compare(final Object o1, final Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());
}
});
// put sorted list into map again
Map sortedMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
private final K key;
private final V value;
private final Map<K, V> map = new HashMap<K, V>();
public TwoWayMap() {
this(null, null);
}
public TwoWayMap(final K key, final V value) {
this.key = key;
this.value = value;
map.put(key, value);
}
/**
* Takes value as input and return key
*
* @param value
* @return key
*/
public K getKey(final V value) {
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
Map.Entry e = (Map.Entry) iter.next();
if (value.equals(e.getValue())) {
return (K) e.getKey();
}
}
return null;
}
/**
* This method return all sorted keys from current map.
*
* @return List<K>
*/
public List<K> getSortedKeys() {
Map<String, String> sortedMap = sortKeyByComparator(map);
List<K> keyList = new ArrayList<K>();
for (Map.Entry entry : sortedMap.entrySet()) {
keyList.add((K) entry.getKey());
}
return keyList;
}
/**
* This method return all sorted values from current map.
*
* @return List<V>
*/
public List<V> getSortedValues() {
Map<String, String> sortedMap = sortValueByComparator(map);
List<V> valueList = new ArrayList<V>();
for (Map.Entry entry : sortedMap.entrySet()) {
valueList.add((V) entry.getValue());
}
return valueList;
}
/**
* This method return value of given key
*
* @param key
* @return return value
*/
public V getValue(final K key) {
return map.get(key);
}
/**
* This method prevent you to put duplicate keys and values, and put unique key and value in map.
*
* @param key
* @param value
* @throws DuplicationKeyException
* when you put same key in map.
* @throws DuplicationValueException
* when you put same value in map
*/
public void put(final K key, final V value) throws DuplicationKeyException, DuplicationValueException {
if (getValue(key) != null && getKey(value) != null) {
throw new DuplicationValueException("Please put unique key and unique value");
}
if (getKey(value) != null) {
throw new DuplicationKeyException("Please put unique value");
}
if (getValue(key) != null) {
throw new DuplicationValueException("Please put unique key");
}
map.put(key, value);
}
/**
* remove map entry by key.
*
* @param key
*/
public void removeByKey(final K key) {
map.remove(key);
}
/**
* remove map entry by value.
*
* @param key
*/
public void removeByValue(final V value) {
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
Map.Entry e = (Map.Entry) iter.next();
if (value.equals(e.getValue())) {
map.remove(e.getKey());
break;
}
}
}
}