MultiMap.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ostrichemulators.semtool.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author ryan
* @param <T>
* @param <V>
*/
public class MultiMap<T, V> extends HashMap<T, List<V>> {
@Override
public List<V> put( T key, List<V> value ) {
return super.put( key, value );
}
public List<V> add( T key, V value ) {
List<V> list;
list = ( containsKey( key ) ? get( key ) : new ArrayList<>() );
list.add( value );
return put( key, list );
}
public List<V> addAll( T key, Collection<V> values ) {
List<V> list = ( containsKey( key ) ? get( key ) : new ArrayList<>() );
list.addAll( values );
return put( key, list );
}
/**
* Gets a guaranteed not-null list of Vs. This is different from
* {@link #get(java.lang.Object) } in that it will never return
* <code>null</code>. If the key *is* present, the list is a reference to the
* list of values, so changes to it will be reflected in this map. If the key
* is *not* present, the changes to the returned list will not be reflected in
* the map.
*
* @param key the key to get
* @return a list
*/
public List<V> getNN( T key ) {
List<V> v = get( key );
return ( null == v ? new ArrayList<>() : v );
}
/**
* Flips the map such that keys become values, and values, keys. If there are
* multiple keys with the same value, the values are added to the MultiMap's
* list
*
* @param <T>
* @param <V>
* @param map
* @return
*/
public static <T, V> MultiMap<T, V> flip( Map<V, T> map ) {
MultiMap<T, V> multi = new MultiMap<>();
for ( Map.Entry<V, T> en : map.entrySet() ) {
multi.add( en.getValue(), en.getKey() );
}
return multi;
}
/**
* Flips the given mapping. This will result in loss of information if the
* original map's values are not unique.
*
* @param <T>
* @param <V>
* @param map
* @return
*/
public static <T, V> Map<T, V> lossyflip( Map<V, T> map ) {
Map<T, V> multi = new HashMap<>();
for ( Map.Entry<V, T> en : map.entrySet() ) {
multi.put( en.getValue(), en.getKey() );
}
return multi;
}
}