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; }