001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.bootjar.java.util;
006:
007: import com.tc.exception.ImplementMe;
008: import com.tc.object.MockTCObject;
009: import com.tc.object.ObjectID;
010: import com.tc.object.PortabilityImpl;
011: import com.tc.object.SerializationUtil;
012: import com.tc.object.TestClientObjectManager;
013: import com.tc.object.MockTCObject.MethodCall;
014: import com.tc.object.bytecode.Manageable;
015: import com.tc.object.config.DSOClientConfigHelper;
016: import com.tc.object.loaders.IsolationClassLoader;
017: import com.tc.object.tx.MockTransactionManager;
018: import com.tc.test.TCTestCase;
019: import com.tc.util.Assert;
020: import com.tc.util.runtime.Vm;
021:
022: import java.lang.reflect.Constructor;
023: import java.lang.reflect.InvocationHandler;
024: import java.lang.reflect.InvocationTargetException;
025: import java.lang.reflect.Method;
026: import java.lang.reflect.Proxy;
027: import java.security.SecureRandom;
028: import java.util.Collection;
029: import java.util.HashMap;
030: import java.util.Iterator;
031: import java.util.List;
032: import java.util.Map;
033: import java.util.Random;
034: import java.util.Set;
035: import java.util.Map.Entry;
036:
037: public class HashMapTCTest extends TCTestCase {
038: private ClassLoader origThreadContextClassLoader;
039:
040: protected void setUp() throws Exception {
041: ClassLoader loader = getClass().getClassLoader();
042: InvocationHandler handler = new InvocationHandler() {
043: public Object invoke(Object proxy, Method method,
044: Object[] args) throws Throwable {
045: String name = method.getName();
046: if ("getNewCommonL1Config".equals(name)
047: || "getInstrumentationLoggingOptions"
048: .equals(name)
049: || "instrumentationLoggingOptions".equals(name)
050: || "getLogicalExtendingClassName".equals(name)
051: || "createDsoClassAdapterFor".equals(name)
052: || "getModulesForInitialization".equals(name)
053: || "verifyBootJarContents".equals(name)) {
054: return null;
055: } else if ("shouldBeAdapted".equals(name)) {
056: return Boolean.FALSE;
057: } else if ("isNeverAdaptable".equals(name)) {
058: return Boolean.TRUE;
059: } else if ("isLogical".equals(name)) {
060: return Boolean.TRUE;
061: } else if ("getAspectModules".equals(name)) {
062: return new HashMap();
063: } else if ("getPortability".equals(name)) {
064: return new PortabilityImpl(
065: (DSOClientConfigHelper) proxy);
066: } else if (Vm.isIBM()
067: && "isRoot".equals(name)
068: && ("java.lang.reflect.Method".equals(args[0]) || "java.lang.reflect.Constructor"
069: .equals(args[0]))) {
070: // the implementation of java.lang.Class in the IBM JDK is different and caches
071: // fields of the Method and Constructor classes, which it retrieves afterwards by
072: // calling the Field.get method. This gets into the AccessibleObject changes for
073: // DSO, which checks if the returned value is a root
074: return Boolean.FALSE;
075: }
076:
077: throw new ImplementMe();
078: }
079: };
080: Object proxy = Proxy.newProxyInstance(loader,
081: new Class[] { DSOClientConfigHelper.class }, handler);
082:
083: TestClientObjectManager testClientObjectManager = new TestClientObjectManager();
084: MockTransactionManager testTransactionManager = new MockTransactionManager();
085: IsolationClassLoader classLoader = new IsolationClassLoader(
086: (DSOClientConfigHelper) proxy, testClientObjectManager,
087: testTransactionManager);
088: classLoader.init();
089:
090: this .origThreadContextClassLoader = Thread.currentThread()
091: .getContextClassLoader();
092: Thread.currentThread().setContextClassLoader(classLoader);
093: }
094:
095: protected void tearDown() throws Exception {
096: super .tearDown();
097:
098: Thread.currentThread().setContextClassLoader(
099: this .origThreadContextClassLoader);
100: }
101:
102: public void testLogicalInvoke() throws Exception {
103: Map tcmap = createMap("java.util.HashMap");
104: validateLogicalInvoke(tcmap);
105:
106: tcmap = createMap("java.util.LinkedHashMap");
107: validateLogicalInvoke(tcmap);
108:
109: tcmap = createMap("java.util.Hashtable");
110: validateLogicalInvoke(tcmap);
111: }
112:
113: public void BROKENtestMapNotShared() throws Exception {
114: Map jmap = createMap("java.util.HashMap_J");
115: Map tcmap = createMap("java.util.HashMap");
116: validateMapNotShared(jmap, tcmap);
117:
118: jmap = createMap("java.util.LinkedHashMap_J");
119: tcmap = createMap("java.util.LinkedHashMap");
120: validateMapNotShared(jmap, tcmap);
121:
122: jmap = createMap("java.util.Hashtable_J");
123: tcmap = createMap("java.util.Hashtable");
124: validateMapNotShared(jmap, tcmap);
125: }
126:
127: public void BROKENtestEntrySet() throws Exception {
128: Map jmap = createMap("java.util.HashMap_J");
129: Map tcmap = createMap("java.util.HashMap");
130: validateEntrySet(jmap, tcmap);
131:
132: jmap = createMap("java.util.LinkedHashMap_J");
133: tcmap = createMap("java.util.LinkedHashMap");
134: validateEntrySet(jmap, tcmap);
135:
136: jmap = createMap("java.util.Hashtable_J");
137: tcmap = createMap("java.util.Hashtable");
138: validateEntrySet(jmap, tcmap);
139: }
140:
141: public void BROKENtestEntrySetAdd() throws Exception {
142: // no test for entrySet().add as it throws an UnsupportedOperationException by design.
143: }
144:
145: public void BROKENtestEntrySetRemove() throws Exception {
146: Map jmap = createMap("java.util.HashMap_J");
147: Map tcmap = createMap("java.util.HashMap");
148: validateEntrySetRemove(jmap, tcmap);
149:
150: jmap = createMap("java.util.LinkedHashMap_J");
151: tcmap = createMap("java.util.LinkedHashMap");
152: validateEntrySetRemove(jmap, tcmap);
153:
154: jmap = createMap("java.util.Hashtable_J");
155: tcmap = createMap("java.util.Hashtable");
156: validateEntrySetRemove(jmap, tcmap);
157: }
158:
159: public void BROKENtestEntrySetClear() throws Exception {
160: Map jmap = createMap("java.util.HashMap_J");
161: Map tcmap = createMap("java.util.HashMap");
162: validateEntrySetClear(jmap, tcmap);
163:
164: jmap = createMap("java.util.LinkedHashMap_J");
165: tcmap = createMap("java.util.LinkedHashMap");
166: validateEntrySetClear(jmap, tcmap);
167:
168: jmap = createMap("java.util.Hashtable_J");
169: tcmap = createMap("java.util.Hashtable");
170: validateEntrySetClear(jmap, tcmap);
171: }
172:
173: public void validateEntrySetIteratorRemove() throws Exception {
174: Map jmap = createMap("java.util.HashMap_J");
175: Map tcmap = createMap("java.util.HashMap");
176: validateEntryIteratorRemove(jmap, tcmap);
177:
178: jmap = createMap("java.util.LinkedHashMap_J");
179: tcmap = createMap("java.util.LinkedHashMap");
180: validateEntryIteratorRemove(jmap, tcmap);
181:
182: jmap = createMap("java.util.Hashtable_J");
183: tcmap = createMap("java.util.Hashtable");
184: validateEntryIteratorRemove(jmap, tcmap);
185: }
186:
187: public void BROKENtestKeySet() throws Exception {
188: Map jmap = createMap("java.util.HashMap_J");
189: Map tcmap = createMap("java.util.HashMap");
190: validateKeySet(jmap, tcmap);
191:
192: jmap = createMap("java.util.LinkedHashMap_J");
193: tcmap = createMap("java.util.LinkedHashMap");
194: validateKeySet(jmap, tcmap);
195:
196: jmap = createMap("java.util.Hashtable_J");
197: tcmap = createMap("java.util.Hashtable");
198: validateKeySet(jmap, tcmap);
199: }
200:
201: public void BROKENtestKeySetRemove() throws Exception {
202: Map jmap = createMap("java.util.HashMap_J");
203: Map tcmap = createMap("java.util.HashMap");
204: validateKeySetRemove(jmap, tcmap);
205:
206: jmap = createMap("java.util.LinkedHashMap_J");
207: tcmap = createMap("java.util.LinkedHashMap");
208: validateKeySetRemove(jmap, tcmap);
209:
210: jmap = createMap("java.util.Hashtable_J");
211: tcmap = createMap("java.util.Hashtable");
212: validateKeySetRemove(jmap, tcmap);
213: }
214:
215: public void BROKENtestKeySetClear() throws Exception {
216: Map jmap = createMap("java.util.HashMap_J");
217: Map tcmap = createMap("java.util.HashMap");
218: validateKeySetClear(jmap, tcmap);
219:
220: jmap = createMap("java.util.LinkedHashMap_J");
221: tcmap = createMap("java.util.LinkedHashMap");
222: validateKeySetClear(jmap, tcmap);
223:
224: jmap = createMap("java.util.Hashtable_J");
225: tcmap = createMap("java.util.Hashtable");
226: validateKeySetClear(jmap, tcmap);
227: }
228:
229: public void BROKENtestKeySetIteratorRemove() throws Exception {
230: Map jmap = createMap("java.util.HashMap_J");
231: Map tcmap = createMap("java.util.HashMap");
232: validateKeySetIteratorRemove(jmap, tcmap);
233:
234: jmap = createMap("java.util.LinkedHashMap_J");
235: tcmap = createMap("java.util.LinkedHashMap");
236: validateKeySetIteratorRemove(jmap, tcmap);
237:
238: jmap = createMap("java.util.Hashtable_J");
239: tcmap = createMap("java.util.Hashtable");
240: validateKeySetIteratorRemove(jmap, tcmap);
241: }
242:
243: public void BROKENtestValues() throws Exception {
244: Map jmap = createMap("java.util.HashMap_J");
245: Map tcmap = createMap("java.util.HashMap");
246: validateValues(jmap, tcmap);
247:
248: jmap = createMap("java.util.LinkedHashMap_J");
249: tcmap = createMap("java.util.LinkedHashMap");
250: validateValues(jmap, tcmap);
251:
252: jmap = createMap("java.util.Hashtable_J");
253: tcmap = createMap("java.util.Hashtable");
254: validateValues(jmap, tcmap);
255: }
256:
257: public void BROKENtestValuesRemove() throws Exception {
258: Map jmap = createMap("java.util.HashMap_J");
259: Map tcmap = createMap("java.util.HashMap");
260: validateValuesRemove(jmap, tcmap);
261:
262: jmap = createMap("java.util.LinkedHashMap_J");
263: tcmap = createMap("java.util.LinkedHashMap");
264: validateValuesRemove(jmap, tcmap);
265:
266: jmap = createMap("java.util.Hashtable_J");
267: tcmap = createMap("java.util.Hashtable");
268: validateValuesRemove(jmap, tcmap);
269: }
270:
271: public void BROKENtestValuesClear() throws Exception {
272: Map jmap = createMap("java.util.HashMap_J");
273: Map tcmap = createMap("java.util.HashMap");
274: validateValuesClear(jmap, tcmap);
275:
276: jmap = createMap("java.util.LinkedHashMap_J");
277: tcmap = createMap("java.util.LinkedHashMap");
278: validateValuesClear(jmap, tcmap);
279:
280: jmap = createMap("java.util.Hashtable_J");
281: tcmap = createMap("java.util.Hashtable");
282: validateValuesClear(jmap, tcmap);
283: }
284:
285: public void BROKENtestValuesIteratorRemove() throws Exception {
286: Map jmap = createMap("java.util.HashMap_J");
287: Map tcmap = createMap("java.util.HashMap");
288: validateValuesIteratorRemove(jmap, tcmap);
289:
290: jmap = createMap("java.util.LinkedHashMap_J");
291: tcmap = createMap("java.util.LinkedHashMap");
292: validateValuesIteratorRemove(jmap, tcmap);
293:
294: jmap = createMap("java.util.Hashtable_J");
295: tcmap = createMap("java.util.Hashtable");
296: validateValuesIteratorRemove(jmap, tcmap);
297: }
298:
299: /** ****************************************************************************** */
300:
301: public void validateLogicalInvoke(Map tcmap) throws Exception {
302:
303: MockTCObject tcObject = new MockTCObject(new ObjectID(1), this ,
304: false, true);
305:
306: ((Manageable) tcmap).__tc_managed(tcObject);
307: SecureRandom sr = new SecureRandom();
308: long seed = sr.nextLong();
309: populateMap(tcmap, new Random(seed), 100);
310:
311: List logicalInvokeHistory = tcObject.getHistory();
312:
313: assertEqualsContent(logicalInvokeHistory, tcmap);
314: }
315:
316: public void validateMapNotShared(Map jmap, Map tcmap)
317: throws Exception {
318: SecureRandom sr = new SecureRandom();
319: long seed = sr.nextLong();
320: System.err.println("Seed is " + seed);
321: populateMap(jmap, new Random(seed));
322: populateMap(tcmap, new Random(seed));
323:
324: assertEquals(jmap, tcmap);
325:
326: System.err.println("Size is " + tcmap.size());
327: assertEquals(tcmap, jmap);
328: }
329:
330: public void validateEntrySet(Map jmap, Map tcmap) throws Exception {
331: SecureRandom sr = new SecureRandom();
332: long seed = sr.nextLong();
333: populateMap(jmap, new Random(seed));
334: populateMap(tcmap, new Random(seed));
335:
336: assertEqualsCollection(jmap.entrySet(), tcmap.entrySet());
337: }
338:
339: public void validateEntrySetRemove(Map jmap, Map tcmap)
340: throws Exception {
341: populateMapWithHashKey(jmap, 100);
342: populateMapWithHashKey(tcmap, 100);
343:
344: Map.Entry entryToBeRemove = new SimpleEntry(new HashKey(10),
345: new HashValue(10));
346:
347: Set tcentrySet = tcmap.entrySet();
348: tcentrySet.remove(entryToBeRemove);
349:
350: Set jentrySet = jmap.entrySet();
351: jentrySet.remove(entryToBeRemove);
352:
353: assertEquals(99, jmap.size());
354: assertEquals(99, tcmap.size());
355: assertEquals(jmap, tcmap);
356: assertEquals(tcmap, jmap);
357: }
358:
359: public void validateEntrySetClear(Map jmap, Map tcmap)
360: throws Exception {
361: populateMapWithHashKey(jmap, 100);
362: populateMapWithHashKey(tcmap, 100);
363:
364: Set tcentrySet = tcmap.entrySet();
365: tcentrySet.clear();
366:
367: Set jentrySet = jmap.entrySet();
368: jentrySet.clear();
369:
370: assertEquals(0, jmap.size());
371: assertEquals(0, tcmap.size());
372: }
373:
374: public void validateEntryIteratorRemove(Map jmap, Map tcmap)
375: throws Exception {
376: populateMapWithHashKey(jmap, 100);
377: populateMapWithHashKey(tcmap, 100);
378:
379: Iterator tcIterator = tcmap.entrySet().iterator();
380: tcIterator.next();
381: tcIterator.next();
382: tcIterator.remove();
383:
384: Iterator jIterator = jmap.entrySet().iterator();
385: jIterator.next();
386: jIterator.next();
387: jIterator.remove();
388:
389: assertEquals(99, jmap.size());
390: assertEquals(99, tcmap.size());
391: assertEquals(jmap, tcmap);
392: assertEquals(tcmap, jmap);
393: }
394:
395: public void validateKeySet(Map jmap, Map tcmap) throws Exception {
396: SecureRandom sr = new SecureRandom();
397: long seed = sr.nextLong();
398: populateMap(jmap, new Random(seed));
399: populateMap(tcmap, new Random(seed));
400:
401: assertEqualsCollection(jmap.keySet(), tcmap.keySet());
402: }
403:
404: public void validateKeySetRemove(Map jmap, Map tcmap)
405: throws Exception {
406: populateMapWithHashKey(jmap, 100);
407: populateMapWithHashKey(tcmap, 100);
408:
409: HashKey keyToBeRemoved = new HashKey(10);
410:
411: Set tckeySet = tcmap.keySet();
412: tckeySet.remove(keyToBeRemoved);
413:
414: Set jkeySet = jmap.keySet();
415: jkeySet.remove(keyToBeRemoved);
416:
417: assertEquals(99, jmap.size());
418: assertEquals(99, tcmap.size());
419: assertEquals(jmap, tcmap);
420: assertEquals(tcmap, jmap);
421: }
422:
423: public void validateKeySetClear(Map jmap, Map tcmap)
424: throws Exception {
425: populateMapWithHashKey(jmap, 100);
426: populateMapWithHashKey(tcmap, 100);
427:
428: Set tckeySet = tcmap.keySet();
429: tckeySet.clear();
430:
431: Set jkeySet = jmap.keySet();
432: jkeySet.clear();
433:
434: assertEquals(0, jmap.size());
435: assertEquals(0, tcmap.size());
436: }
437:
438: public void validateKeySetIteratorRemove(Map jmap, Map tcmap)
439: throws Exception {
440: populateMapWithHashKey(jmap, 100);
441: populateMapWithHashKey(tcmap, 100);
442:
443: Iterator tciterator = tcmap.keySet().iterator();
444: tciterator.next();
445: tciterator.next();
446: tciterator.remove();
447:
448: Iterator jiterator = jmap.keySet().iterator();
449: jiterator.next();
450: jiterator.next();
451: jiterator.remove();
452:
453: assertEquals(99, jmap.size());
454: assertEquals(99, tcmap.size());
455: assertEquals(jmap, tcmap);
456: assertEquals(tcmap, jmap);
457: }
458:
459: public void validateValues(Map jmap, Map tcmap) throws Exception {
460: SecureRandom sr = new SecureRandom();
461: long seed = sr.nextLong();
462: populateMap(jmap, new Random(seed));
463: populateMap(tcmap, new Random(seed));
464:
465: assertEqualsCollection(jmap.values(), tcmap.values());
466: }
467:
468: public void validateValuesRemove(Map jmap, Map tcmap)
469: throws Exception {
470: populateMapWithHashKey(jmap, 100);
471: populateMapWithHashKey(tcmap, 100);
472:
473: HashValue valueToBeRemoved = new HashValue(10);
474:
475: Collection tcvalues = tcmap.values();
476: tcvalues.remove(valueToBeRemoved);
477:
478: Collection jvalues = jmap.values();
479: jvalues.remove(valueToBeRemoved);
480:
481: assertEquals(99, jmap.size());
482: assertEquals(99, tcmap.size());
483: assertEquals(jmap, tcmap);
484: assertEquals(tcmap, jmap);
485: }
486:
487: public void validateValuesClear(Map jmap, Map tcmap)
488: throws Exception {
489: populateMapWithHashKey(jmap, 100);
490: populateMapWithHashKey(tcmap, 100);
491:
492: Collection tcvalues = tcmap.values();
493: tcvalues.clear();
494:
495: Collection jvalues = jmap.values();
496: jvalues.clear();
497:
498: assertEquals(0, jmap.size());
499: assertEquals(0, tcmap.size());
500: }
501:
502: public void validateValuesIteratorRemove(Map jmap, Map tcmap)
503: throws Exception {
504: populateMapWithHashKey(jmap, 100);
505: populateMapWithHashKey(tcmap, 100);
506:
507: Iterator tciterator = tcmap.values().iterator();
508: tciterator.next();
509: tciterator.next();
510: tciterator.remove();
511:
512: Iterator jiterator = jmap.values().iterator();
513: jiterator.next();
514: jiterator.next();
515: jiterator.remove();
516:
517: assertEquals(99, jmap.size());
518: assertEquals(99, tcmap.size());
519: assertEquals(jmap, tcmap);
520: assertEquals(tcmap, jmap);
521: }
522:
523: void assertSingleMapping(Map map, final Object key,
524: final Object value) {
525: Assert.assertFalse(map.isEmpty());
526: Assert.assertEquals(1, map.size());
527: Assert.assertEquals(1, map.entrySet().size());
528: Assert.assertEquals(1, map.values().size());
529: Assert.assertEquals(1, map.keySet().size());
530: Assert.assertEquals(value, map.get(key));
531: Assert.assertTrue(map.containsKey(key));
532: Assert.assertTrue(map.containsValue(value));
533:
534: Set entries = map.entrySet();
535: for (Iterator i = entries.iterator(); i.hasNext();) {
536: Entry entry = (Entry) i.next();
537: Assert.assertEquals(key, entry.getKey());
538: Assert.assertEquals(value, entry.getValue());
539: }
540:
541: for (Iterator i = map.values().iterator(); i.hasNext();) {
542: Object o = i.next();
543: Assert.assertEquals(value, o);
544: }
545:
546: for (Iterator i = map.keySet().iterator(); i.hasNext();) {
547: Object o = i.next();
548: Assert.assertEquals(key, o);
549: }
550:
551: HashMap compare = new HashMap();
552: compare.put(key, value);
553: Assert.assertEquals(compare, map);
554: }
555:
556: private void assertEqualsContent(Collection expected, Map actual) {
557: assertEquals(expected.size(), actual.size());
558:
559: Set keySet = actual.keySet();
560: for (Iterator i = expected.iterator(); i.hasNext();) {
561: MethodCall methodCall = (MethodCall) i.next();
562: assertEquals(SerializationUtil.PUT, methodCall.method);
563:
564: assertTrue(keySet.contains(methodCall.parameters[0]));
565: assertEquals(methodCall.parameters[1], actual
566: .get(methodCall.parameters[0]));
567: }
568: }
569:
570: private void assertEqualsCollection(Collection expected,
571: Collection actual) {
572: assertEquals(expected.size(), actual.size());
573:
574: for (Iterator i = expected.iterator(), j = actual.iterator(); i
575: .hasNext();) {
576: Object expectedObject = i.next();
577: Object actualObject = j.next();
578: assertEquals(expectedObject, actualObject);
579: }
580: }
581:
582: private Map createMap(String className)
583: throws ClassNotFoundException, SecurityException,
584: NoSuchMethodException, IllegalArgumentException,
585: InstantiationException, IllegalAccessException,
586: InvocationTargetException {
587: Class c = Class.forName(className);
588: Constructor constructor = c.getConstructor(new Class[0]);
589: return (Map) constructor.newInstance(new Object[0]);
590: }
591:
592: private void populateMapWithHashKey(Map map, int numOfItems) {
593: for (int i = 0; i < numOfItems; i++) {
594: map.put(new HashKey(i), new HashValue(i));
595: }
596: }
597:
598: private void populateMap(Map map, Random r) {
599: populateMap(map, r, 10000);
600: }
601:
602: private void populateMap(Map map, Random r, int numOfItems) {
603: for (int i = 0; i < numOfItems; i++) {
604: switch (i % 4) {
605: case 0:
606: map.put(new Long(r.nextLong()), "Long to String");
607: break;
608: case 1:
609: map.put(new Integer(r.nextInt()), "Integer to String");
610: break;
611: case 2:
612: map.put(String.valueOf(r.nextLong()),
613: "String to String");
614: break;
615: case 3:
616: map.put(new ObjectID(r.nextLong()),
617: "ObjectID to String");
618: break;
619: default:
620: // Should never come here
621: throw new AssertionError();
622: }
623: }
624: }
625:
626: private static class SimpleEntry implements Map.Entry {
627:
628: private final Object key;
629: private Object value;
630:
631: public SimpleEntry(Object key, Object value) {
632: this .key = key;
633: this .value = value;
634: }
635:
636: public SimpleEntry(Map.Entry e) {
637: this .key = e.getKey();
638: this .value = e.getValue();
639: }
640:
641: public Object getKey() {
642: return key;
643: }
644:
645: public Object getValue() {
646: return value;
647: }
648:
649: public Object setValue(Object value) {
650: Object oldValue = this .value;
651: this .value = value;
652: return oldValue;
653: }
654:
655: public boolean equals(Object o) {
656: if (!(o instanceof Map.Entry))
657: return false;
658: Map.Entry e = (Map.Entry) o;
659: return eq(key, e.getKey()) && eq(value, e.getValue());
660: }
661:
662: public int hashCode() {
663: return ((key == null) ? 0 : key.hashCode())
664: ^ ((value == null) ? 0 : value.hashCode());
665: }
666:
667: public String toString() {
668: return key + "=" + value;
669: }
670:
671: private static boolean eq(Object o1, Object o2) {
672: return (o1 == null ? o2 == null : o1.equals(o2));
673: }
674: }
675:
676: private static class HashKey {
677: private int i;
678:
679: public HashKey(int i) {
680: super ();
681: this .i = i;
682: }
683:
684: public int getInt() {
685: return this .i;
686: }
687:
688: public int hashCode() {
689: return i;
690: }
691:
692: public boolean equals(Object obj) {
693: if (obj == null)
694: return false;
695: if (!(obj instanceof HashKey))
696: return false;
697: return ((HashKey) obj).i == i;
698: }
699: }
700:
701: private static class HashValue {
702: private int i;
703:
704: public HashValue(int i) {
705: super ();
706: this .i = i;
707: }
708:
709: public int getInt() {
710: return this .i;
711: }
712:
713: public int hashCode() {
714: return i;
715: }
716:
717: public boolean equals(Object obj) {
718: if (obj == null)
719: return false;
720: if (!(obj instanceof HashValue))
721: return false;
722: return ((HashValue) obj).i == i;
723: }
724:
725: public String toString() {
726: return super .toString() + ", i: " + i;
727: }
728: }
729:
730: }
|