001 // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org)
002 // The Molly framework is freely distributable under the terms of an
003 // MIT-style license. For details, see the molly pages web site at:
004 // http://www.mollypages.org/. Use, modify, have fun !
005
006 package fc.util;
007
008 import java.util.*;
009
010 /**
011 Implements a simple table data structure. Like a 2D array
012 but uses nested hash tables to get (row, col) based on a
013 (name, name) pair. The table grows automatically as needed.
014 <p>
015 Differs from a 2D Object[][] in that names can be used
016 instead of indices.
017 <p>
018 All indexes are internally strings. When adding or retrieving
019 values, either numerical and string indices can be specified
020 for either row or col when retrieving a (row,col) value. <i>A
021 numerical index is converted into a string value</i> so if one puts
022 a value at (3, 5), that can later be retrieved as ("3", "5")
023 if desired.
024 <p>
025 Thread safety: This data structure is fully thread safe.
026
027 @author hursh jain
028 **/
029 public final class Table
030 {
031 private static final boolean dbg = false;
032
033 int row_default_size;
034 int col_default_size;
035
036 /*
037 A B C
038 rows 1: x y z
039 2: a e n
040 3: c d m
041
042 rows(1) => hashtable (A->x, B->y, C->z)
043 rows(2) => hashtable (A->a, B->e, C->n)
044 ..
045 */
046 Map table;
047
048 /**
049 Constructs a new table.
050 **/
051 public Table() {
052 this(32, 32);
053 }
054
055 /**
056 Constructs a new table of the specified initial size.
057 **/
058 public Table(int rows, int cols) {
059 this.row_default_size = rows;
060 this.col_default_size = cols;
061 this.table = new Hashtable(rows);
062 }
063
064 /**
065 Returns the object at row, col or <tt>null</tt> if the
066 specified row or col do not exist.
067 */
068 public Object get(String row, String col)
069 {
070 Object val = null;
071
072 Map cols = (Map) table.get(row);
073
074 if (cols != null)
075 val = cols.get(col);
076
077 return val;
078 }
079
080
081 /**
082 Returns the object at row, col or <tt>null</tt> if the
083 specified row or col do not exist.
084 */
085 public Object get(int row, String col)
086 {
087 return get(String.valueOf(row), col);
088 }
089
090 /**
091 Returns the object at row, col or <tt>null</tt> if the
092 specified row or col do not exist.
093 */
094 public Object get(String row, int col)
095 {
096 return get(row, String.valueOf(col));
097 }
098
099 /**
100 Returns the object at row, col or <tt>null</tt> if the
101 specified row or col do not exist.
102 */
103 public Object get(int row, int col)
104 {
105 return get(String.valueOf(row), String.valueOf(col));
106 }
107
108 /**
109 Returns the object at row, col or <tt>null</tt> if the
110 specified row or col do not exist.
111
112 @return the old object at that (row, col) if it exists
113 */
114 public Object put(String row, String col, Object obj)
115 {
116 Object val = null;
117
118 Map c = (Map) table.get(row);
119 if (c == null) {
120 c = new Hashtable(col_default_size);
121 table.put(row, c);
122 }
123
124 val = c.put(col, obj);
125 return val;
126 }
127
128
129 public Object put(int row, String col, Object obj)
130 {
131 return put(String.valueOf(row), col, obj);
132 }
133
134 public Object put(String row, int col, Object obj)
135 {
136 return put(row, String.valueOf(col), obj);
137 }
138
139 public Object put(int row, int col, Object obj)
140 {
141 return put(String.valueOf(row), String.valueOf(col), obj);
142 }
143
144
145 public String toString() {
146 return "Table: [" + table.size() + " rows]";
147 }
148
149 public static void main (String args[])
150 {
151 Table t = new Table();
152 System.out.println("t.get(1,1)="+t.get(1,1));
153 System.out.println("t.put(1,1,\"hello\")="+t.put(1,1, "hello"));
154 System.out.println("t.get(\"1\",\"1\")="+t.get("1","1"));
155 System.out.println("t.get(1,\"1\")="+t.get(1,"1"));
156 System.out.println("t.get(1,0)="+t.get(1,0));
157 System.out.println("t.put(1,1,\"hello\")="+t.put(1,1, "world"));
158 System.out.println("t.get(\"1\",1)="+t.get("1",1));
159
160 for (int n = 0; n < 10; n++) {
161 t.put(n, n, n);
162 }
163
164 for (int n = 0; n < 10; n++) {
165 System.out.println("table["+n+","+n+"]:"+t.get(n, n));
166 }
167
168 Watch w = new Watch().start();
169 t.get(5,5);
170 w.stop();
171 System.out.println("time for one t.get() op: " + w.time() + " ms");
172 }
173 } //~class Table