// The top interface for "Hashes" functionality in Java is java.util.Map. Multiple // implementations with some selected added features are available, java.util.HashMap, // java.util.Hashtable, java.util.LinkedHashMap and java.util.TreeMap being the most // notable ones. // // Maps cannot contain primitive types, they must contain objects (int -> Integer). // // Maps don't have "sugar" syntax for easy creation of arbitrary maps, we need to // call several methods for this: Map age = new HashMap(); age.put( "Nat", new Integer( 24 ) ); age.put( "Jules", new Integer( 25 ) ); age.put( "Josh", new Integer( 17 ) ); Map food_color = new HashMap(); food_color.put( "Apple", "red" ); food_color.put( "Banana", "yellow" ); food_color.put( "Lemon", "yellow" ); food_color.put( "Carrot", "orange" ); |
// Setting or replacing a map entry uses Map#put: Map map = new HashMap(); Object key = null; Object value = null; map.put( key, value ); // food_color defined per the introduction; we use an iterator on the keys of the map food_color.put( "Raspberry", "pink" ); System.out.println( "Known foods:" ); for ( Iterator it = food_color.keySet().iterator(); it.hasNext(); ) { System.out.println( it.next() ); } |
// does map have a value for key? if ( map.containsKey( key ) ) { // it exists } else { // it doesn't } String[] food_or_drink = new String[] { "Banana", "Martini" }; for ( int i = 0; i < food_or_drink.length; i++ ) { String name = food_or_drink[i]; System.out.println( name + " is a " + ( food_color.containsKey( name ) ? "food" : "drink" ) ); } age.put( "Toddler", new Integer( 3 ) ); age.put( "Unborn", new Integer( 0 ) ); age.put( "Phantasm", null ); String[] age_tries = new String[] { "Toddler", "Unborn", "Phantasm", "Relic" }; for ( int i = 0; i < age_tries.length; i++ ) { String atry = age_tries[i]; System.out.println( atry + ": " + ( age.containsKey( atry ) ? "contains-key " : "" ) + ( age.containsKey( atry ) && age.get( atry ) != null ? "non-null " : "" ) + ( age.containsKey( atry ) && age.get( atry ) != null && ! ( (Integer)age.get( atry ) ).equals( new Integer( 0 ) ) ? "non-zero" : "" ) ); } // => // Toddler: contains-key non-null non-zero // Unborn: contains-key non-null // Phantasm: contains-key // Relic: // You use Map#containsKey when you use Perl's exists -> it checks // for existence of a key in a Map. |
food_color.remove( "Banana" ); |
for ( Iterator it = food_color.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry) it.next(); // do something with e.getKey() and e.getValue() // also supports e.setValue() to update the value } for ( Iterator it = food_color.keySet().iterator(); it.hasNext(); ) { key = it.next(); // do something with key } for ( Iterator it = food_color.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry) it.next(); System.out.println( e.getKey() + " is " + e.getValue() ); } // The easiest way to iterate over keys of a Map in ordered keys is to use // java.util.TreeMap, which "guarantees that the map will be in ascending // key order, sorted according to the natural order for the key's class". TreeMap sorted_foods = new TreeMap( food_color ); System.out.println( "sorted foods:" ); for ( Iterator it = sorted_foods.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry) it.next(); System.out.println( e.getKey() + " is " + e.getValue() ); } // download the following standalone program import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** countfrom - count number of messages from each sender. */ public class CountFrom { public static void main( String args[] ) throws IOException { TreeMap from = new TreeMap(); BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) ); String line; Pattern p = Pattern.compile( "From: (.*)" ); while ( ( line = br.readLine() ) != null ) { Matcher m = p.matcher( line ); if ( m.lookingAt() ) { Integer current_value = (Integer) from.get( m.group( 1 ) ); if ( current_value == null ) { current_value = new Integer( 1 ); } else { current_value = new Integer( current_value.intValue() + 1 ); } from.put( m.group( 1 ), current_value ); } } for ( Iterator it = from.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry) it.next(); System.out.println( e.getKey() + ": " + e.getValue() ); } } } |
// Map#toString already produce a pretty decent output: System.out.println( sorted_foods ); // => // {Apple=red, Carrot=orange, Lemon=yellow, Raspberry=pink} // Or do it the Cookbook way: for ( Iterator it = sorted_foods.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry) it.next(); System.out.println( e.getKey() + " => " + e.getValue() ); } // => // Apple => red // Carrot => orange // Lemon => yellow // Raspberry => pink |
// java.util.LinkedHashMap "maintains a doubly-linked list running through all of its entries. // This linked list defines the iteration ordering, which is normally the order in which keys // were inserted into the map (insertion-order)". food_color = new LinkedHashMap(); food_color.put( "Banana", "Yellow" ); food_color.put( "Apple", "Green" ); food_color.put( "Lemon", "Yellow" ); System.out.println( "In insertion order, the foods are:" ); for ( Iterator it = food_color.keySet().iterator(); it.hasNext(); ) { System.out.println( it.next() ); } // => // Banana // Apple // Lemon |