MultiSetMap.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.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
*
* @author ryan
* @param <T>
* @param <V>
*/
public class MultiSetMap<T, V> extends HashMap<T, Set<V>> {
public static <K, X> MultiSetMap<K, X> deepCopy( Map<K, Set<X>> model ) {
MultiSetMap<K, X> newmap = new MultiSetMap<>();
for ( Map.Entry<K, Set<X>> en : model.entrySet() ) {
Set<X> newv = new LinkedHashSet<>();
for ( X v : en.getValue() ) {
newv.add( v );
}
newmap.put( en.getKey(), newv );
}
return newmap;
}
@Override
public Set<V> put( T key, Set<V> value ) {
return super.put( key, value );
}
public Set<V> add( T key, V value ) {
Set<V> list;
list = ( containsKey( key ) ? get( key ) : new LinkedHashSet<>() );
list.add( value );
return put( key, list );
}
public Set<V> addAll( T key, Collection<V> vals ) {
if ( containsKey( key ) ) {
get( key ).addAll( vals );
}
else {
put( key, new LinkedHashSet<>( vals ) );
}
return get( key );
}
/**
* Gets a guaranteed not-null (but possibly empty) set of Vs. This set has a
* consistent iteration order. 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
* set of values, so changes to it will be reflected in this map. If the key
* is *not* present, the changes to the returned set will not be reflected in
* the map.
*
* @param key the key to get
* @return a list
*/
public Set<V> getNN( T key ) {
Set<V> v = get( key );
return ( null == v ? new LinkedHashSet<>() : v );
}
public static <T, V> MultiSetMap<T, V> flip( Map<V, T> map ) {
MultiSetMap<T, V> multi = new MultiSetMap<>();
for ( Map.Entry<V, T> en : map.entrySet() ) {
multi.add( en.getValue(), en.getKey() );
}
return multi;
}
}