1 package org.antlr.runtime.misc; 2 3 import java.util.*; 4 5 /** Sometimes we need to map a key to a value but key is two pieces of data. 6 * This nested hash table saves creating a single key each time we access 7 * map; avoids mem creation. 8 */ 9 public class DoubleKeyMap<Key1, Key2, Value> { 10 Map<Key1, Map<Key2, Value>> data = new LinkedHashMap<Key1, Map<Key2, Value>>(); 11 12 public Value put(Key1 k1, Key2 k2, Value v) { 13 Map<Key2, Value> data2 = data.get(k1); 14 Value prev = null; 15 if ( data2==null ) { 16 data2 = new LinkedHashMap<Key2, Value>(); 17 data.put(k1, data2); 18 } 19 else { 20 prev = data2.get(k2); 21 } 22 data2.put(k2, v); 23 return prev; 24 } 25 26 public Value get(Key1 k1, Key2 k2) { 27 Map<Key2, Value> data2 = data.get(k1); 28 if ( data2==null ) return null; 29 return data2.get(k2); 30 } 31 32 public Map<Key2, Value> get(Key1 k1) { return data.get(k1); } 33 34 /** Get all values associated with primary key */ 35 public Collection<Value> values(Key1 k1) { 36 Map<Key2, Value> data2 = data.get(k1); 37 if ( data2==null ) return null; 38 return data2.values(); 39 } 40 41 /** get all primary keys */ 42 public Set<Key1> keySet() { 43 return data.keySet(); 44 } 45 46 /** get all secondary keys associated with a primary key */ 47 public Set<Key2> keySet(Key1 k1) { 48 Map<Key2, Value> data2 = data.get(k1); 49 if ( data2==null ) return null; 50 return data2.keySet(); 51 } 52 53 public Collection<Value> values() { 54 Set<Value> s = new HashSet<Value>(); 55 for (Map<Key2, Value> k2 : data.values()) { 56 for (Value v : k2.values()) { 57 s.add(v); 58 } 59 } 60 return s; 61 } 62 } 63