This is a collection of cool things to do with maps as they are encountered and I get excited enough to write them down. (I'm getting long enough in the Java tooth that I don't always recognize when I should note something for general interest.)
Here's a neat trick that works real well. It's just complicated enough that it might not occur to you. This is Java 5+ stuff, of course.
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
public class Ratings
{
// ratings...
public static final int NR = 0; // not rated
public static final int G = 1; // general admission
public static final int PG = 2; // parental guidance suggested
public static final int PG_13 = 3; // parent guidance strongly suggested/not under 13
public static final int R = 5; // restricted to mature audiences
public static final Map< Integer, String > RATINGS;
static
{
Map< Integer, String > map = new HashMap<>();
map.put( NR, "NR" );
map.put( G, "G" );
map.put( PG, "PG" );
map.put( PG_13, "PG_13" );
map.put( R, "R" );
RATINGS = Collections.unmodifiableMap( map );
}
}
Afterward, it's easy to write code to convert from the integer (say, from a database column) to string and vice-versa. It's also possible to use the integer variables as "manifest constants."
...or...
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
private static final Map< String, Integer > permissions = new HashMap< String, Integer >()
{
{
put( "password", new Integer( 0 ) );
put( "read", new Integer( 1 ) );
put( "append", new Integer( 2 ) );
put( "write", new Integer( 3 ) );
}
};
private final boolean isSufficient( String horseShoeString, String stakeString )
{
int stake = permissions.get( stakeString );
int horseshoe = permissions.get( horseShoeString );
if( horseshoe == 0 && stake == 0 ) // password is only password, not read or write
return true;
// from here on, it's sort of telescopic...
return( horseshoe >= stake );
}
Traversing a map is a bit challenging. Here are two methods.
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
private static final Map< String, String > permissionTuples = new HashMap< String, String >()
{
{
"Jack", "write",
"Jill", "append",
"Jack", "password",
"Jill", "read",
"Jimmy", "write",
}
};
String name = "Jack";
/* method 1: since Java 5 */
for( Map.Entry< String, String > map : permissions.entrySet() )
{
if( !map.getKey().equals( name ) )
continue;
if( isSufficient( permission, map.getValue() ) )
;
}
/* method 2: the older way */
Iterator< Map.Entry< String, String > > it = permissions.entrySet().iterator();
while( it.hasNext() )
{
Map.Entry< String, String > tuple = ( Map.Entry< String, String > ) it.next();
if( !tuple.getKey().equals( name ) )
continue;
if( isSufficient( permission, tuple.getValue() ) )
;
}
How to traverse a Map four different ways in Java. It's true that all these ways are more or less the same one or two ways, but it's a great illustration I picked up somewhere.
...and imports used in these examples.
import java.util.HashMap; import java.util.Map; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; HashMap< String, String > loans = new HashMap<>(); loans.put( "home loan", "citibank" ); loans.put( "personal loan", "Wells Fargo" );
That is, the for-each style loop from Java 5...
for( String key : loans.keySet() ) System.out.println( "key: " + key + " value: " + loans.get( key ) );
key: home loan value: citibank key: personal loan value: Wells Fargo
Set< String > keySet = loans.keySet();
Iterator< String > keySetIterator = keySet.iterator();
while( keySetIterator.hasNext() )
{
String key = keySetIterator.next();
System.out.println( "key: " + key + " value: " + loans.get( key ) );
}
key: home loan value: citibank key: personal loan value: Wells Fargo
Set< Map.Entry< String, String > > entrySet = loans.entrySet(); for( Entry entry : entrySet ) System.out.println( "key: " + entry.getKey() + " value: " + entry.getValue() );
key: home loan value: citibank key: personal loan value: Wells Fargo
Set< Map.Entry< String, String > > entrySet1 = loans.entrySet();
Iterator< Entry< String, String > > entrySetIterator = entrySet1.iterator();
while( entrySetIterator.hasNext() )
{
Entry entry = entrySetIterator.next();
System.out.println( "key: " + entry.getKey() + " value: " + entry.getValue() );
}
key: home loan value: citibank key: personal loan value: Wells Fargo
/**
* Given a symbol table, and the list of keys (sorted or not) in
* the symbol table, print the keys, one per line, padded to be
* right-aligned with a colon, and their values.
*
* Example
*
* content: 6
* targetSiteCode: 6
* consumable: 6
* manufacturedLabeledDrug: 6
* originalText: 7
* translation: 7
* ExternalObservation: 8
* list: 9
* name: 11
* entryRelationship: 12
* tr: 12
* th: 14
* section: 15
* reference: 15
* title: 16
* component: 16
* td: 18
* text: 23
*
* @param table the symbol tables.
* @param keys the set or a subset of keys in the symbol table.
* @param padding width of the column in which to print the right-aligned keys.
*/
public static void sortAndPrintPaddedByValue( SymbolTable table, List< String > keys, int padding )
{
Map< String, Integer > sortedMap = sortMapByValue( table.map() );
for( Map.Entry< String, Integer > map : sortedMap.entrySet() )
{
Integer value = map.getValue();
String key = map.getKey();
String output = "";
for( int pad = 0; pad < ( padding - key.length() ); pad++ )
output = output + " ";
System.out.println( output + key + ": " + value );
}
}
private static < K, V extends Comparable< ? super V > > Map< K, V > sortMapByValue( Map< K, V > map )
{
List< Map.Entry< K, V > > list = new LinkedList<>( map.entrySet() );
Collections.sort( list, new Comparator< Map.Entry< K, V > >()
{
@Override
public int compare( Entry< K, V > o1, Entry< K, V > o2 )
{
return ( o1.getValue() ).compareTo( ( V ) o2.getValue() );
}
}
);
Map< K, V > result = new LinkedHashMap<>();
for( Map.Entry< K, V > entry : list )
result.put( entry.getKey(), entry.getValue() );
return result;
}