Source Code Cross Referenced for Hashtable.java in  » Apache-Harmony-Java-SE » java-package » java » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » java package » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package java.util;
019:
020:        import java.io.IOException;
021:        import java.io.ObjectInputStream;
022:        import java.io.ObjectOutputStream;
023:        import java.io.Serializable;
024:
025:        import org.apache.harmony.luni.internal.nls.Messages;
026:
027:        /**
028:         * Hashtable associates keys with values. Keys and values cannot be null. The
029:         * size of the Hashtable is the number of key/value pairs it contains. The
030:         * capacity is the number of key/value pairs the Hashtable can hold. The load
031:         * factor is a float value which determines how full the Hashtable gets before
032:         * expanding the capacity. If the load factor of the Hashtable is exceeded, the
033:         * capacity is doubled.
034:         * 
035:         * @see Enumeration
036:         * @see java.io.Serializable
037:         * @see java.lang.Object#equals
038:         * @see java.lang.Object#hashCode
039:         */
040:
041:        public class Hashtable<K, V> extends Dictionary<K, V> implements 
042:                Map<K, V>, Cloneable, Serializable {
043:
044:            private static final long serialVersionUID = 1421746759512286392L;
045:
046:            transient int elementCount;
047:
048:            transient Entry<K, V>[] elementData;
049:
050:            private float loadFactor;
051:
052:            private int threshold;
053:
054:            transient int firstSlot;
055:
056:            transient int lastSlot = -1;
057:
058:            transient int modCount;
059:
060:            private static final Enumeration<?> EMPTY_ENUMERATION = new Enumeration<Object>() {
061:                public boolean hasMoreElements() {
062:                    return false;
063:                }
064:
065:                public Object nextElement() {
066:                    throw new NoSuchElementException();
067:                }
068:            };
069:
070:            private static <K, V> Entry<K, V> newEntry(K key, V value, int hash) {
071:                return new Entry<K, V>(key, value);
072:            }
073:
074:            private static class Entry<K, V> extends MapEntry<K, V> {
075:                Entry<K, V> next;
076:
077:                final int hashcode;
078:
079:                Entry(K theKey, V theValue) {
080:                    super (theKey, theValue);
081:                    hashcode = theKey.hashCode();
082:                }
083:
084:                @Override
085:                @SuppressWarnings("unchecked")
086:                public Object clone() {
087:                    Entry<K, V> entry = (Entry<K, V>) super .clone();
088:                    if (next != null) {
089:                        entry.next = (Entry<K, V>) next.clone();
090:                    }
091:                    return entry;
092:                }
093:
094:                @Override
095:                public V setValue(V object) {
096:                    if (object == null) {
097:                        throw new NullPointerException();
098:                    }
099:                    V result = value;
100:                    value = object;
101:                    return result;
102:                }
103:
104:                public int getKeyHash() {
105:                    return key.hashCode();
106:                }
107:
108:                public boolean equalsKey(Object aKey, int hash) {
109:                    return hashcode == aKey.hashCode() && key.equals(aKey);
110:                }
111:
112:                @Override
113:                public String toString() {
114:                    return key + "=" + value; //$NON-NLS-1$
115:                }
116:            }
117:
118:            private final class HashIterator<E> implements  Iterator<E> {
119:                private int position, expectedModCount;
120:
121:                private final MapEntry.Type<E, K, V> type;
122:
123:                private Entry<K, V> lastEntry;
124:
125:                private int lastPosition;
126:
127:                private boolean canRemove = false;
128:
129:                HashIterator(MapEntry.Type<E, K, V> value) {
130:                    type = value;
131:                    position = lastSlot;
132:                    expectedModCount = modCount;
133:                }
134:
135:                public boolean hasNext() {
136:                    if (lastEntry != null && lastEntry.next != null) {
137:                        return true;
138:                    }
139:                    while (position >= firstSlot) {
140:                        if (elementData[position] == null) {
141:                            position--;
142:                        } else {
143:                            return true;
144:                        }
145:                    }
146:                    return false;
147:                }
148:
149:                public E next() {
150:                    if (expectedModCount == modCount) {
151:                        if (lastEntry != null) {
152:                            lastEntry = lastEntry.next;
153:                        }
154:                        if (lastEntry == null) {
155:                            while (position >= firstSlot
156:                                    && (lastEntry = elementData[position]) == null) {
157:                                position--;
158:                            }
159:                            if (lastEntry != null) {
160:                                lastPosition = position;
161:                                // decrement the position so we don't find the same slot
162:                                // next time
163:                                position--;
164:                            }
165:                        }
166:                        if (lastEntry != null) {
167:                            canRemove = true;
168:                            return type.get(lastEntry);
169:                        }
170:                        throw new NoSuchElementException();
171:                    }
172:                    throw new ConcurrentModificationException();
173:                }
174:
175:                public void remove() {
176:                    if (expectedModCount == modCount) {
177:                        if (canRemove) {
178:                            canRemove = false;
179:                            synchronized (Hashtable.this ) {
180:                                boolean removed = false;
181:                                Entry<K, V> entry = elementData[lastPosition];
182:                                if (entry == lastEntry) {
183:                                    elementData[lastPosition] = entry.next;
184:                                    removed = true;
185:                                } else {
186:                                    while (entry != null
187:                                            && entry.next != lastEntry) {
188:                                        entry = entry.next;
189:                                    }
190:                                    if (entry != null) {
191:                                        entry.next = lastEntry.next;
192:                                        removed = true;
193:                                    }
194:                                }
195:                                if (removed) {
196:                                    modCount++;
197:                                    elementCount--;
198:                                    expectedModCount++;
199:                                    return;
200:                                }
201:                                // the entry must have been (re)moved outside of the
202:                                // iterator
203:                                // but this condition wasn't caught by the modCount
204:                                // check
205:                                // throw ConcurrentModificationException() outside of
206:                                // synchronized block
207:                            }
208:                        } else {
209:                            throw new IllegalStateException();
210:                        }
211:                    }
212:                    throw new ConcurrentModificationException();
213:                }
214:            }
215:
216:            private final class HashEnumerator<E> implements  Enumeration<E> {
217:                boolean key;
218:
219:                int start;
220:
221:                Entry<K, V> entry;
222:
223:                HashEnumerator(boolean isKey) {
224:                    key = isKey;
225:                    start = lastSlot + 1;
226:                }
227:
228:                public boolean hasMoreElements() {
229:                    if (entry != null) {
230:                        return true;
231:                    }
232:                    while (start > firstSlot) {
233:                        if (elementData[--start] != null) {
234:                            entry = elementData[start];
235:                            return true;
236:                        }
237:                    }
238:                    return false;
239:                }
240:
241:                @SuppressWarnings("unchecked")
242:                public E nextElement() {
243:                    if (hasMoreElements()) {
244:                        Object result = key ? entry.key : entry.value;
245:                        entry = entry.next;
246:                        return (E) result;
247:                    }
248:                    throw new NoSuchElementException();
249:                }
250:            }
251:
252:            /**
253:             * Constructs a new Hashtable using the default capacity and load factor.
254:             */
255:            public Hashtable() {
256:                this (11);
257:            }
258:
259:            /**
260:             * Constructs a new Hashtable using the specified capacity and the default
261:             * load factor.
262:             * 
263:             * @param capacity
264:             *            the initial capacity
265:             */
266:            public Hashtable(int capacity) {
267:                if (capacity >= 0) {
268:                    elementCount = 0;
269:                    elementData = newElementArray(capacity == 0 ? 1 : capacity);
270:                    firstSlot = elementData.length;
271:                    loadFactor = 0.75f;
272:                    computeMaxSize();
273:                } else {
274:                    throw new IllegalArgumentException();
275:                }
276:            }
277:
278:            /**
279:             * Constructs a new Hashtable using the specified capacity and load factor.
280:             * 
281:             * @param capacity
282:             *            the initial capacity
283:             * @param loadFactor
284:             *            the initial load factor
285:             */
286:            public Hashtable(int capacity, float loadFactor) {
287:                if (capacity >= 0 && loadFactor > 0) {
288:                    elementCount = 0;
289:                    firstSlot = capacity;
290:                    elementData = newElementArray(capacity == 0 ? 1 : capacity);
291:                    this .loadFactor = loadFactor;
292:                    computeMaxSize();
293:                } else {
294:                    throw new IllegalArgumentException();
295:                }
296:            }
297:
298:            /**
299:             * Constructs a new instance of Hashtable containing the mappings from the
300:             * specified Map.
301:             * 
302:             * @param map
303:             *            the mappings to add
304:             */
305:            public Hashtable(Map<? extends K, ? extends V> map) {
306:                this (map.size() < 6 ? 11 : (map.size() * 4 / 3) + 11);
307:                putAll(map);
308:            }
309:
310:            @SuppressWarnings("unchecked")
311:            private Entry<K, V>[] newElementArray(int size) {
312:                return new Entry[size];
313:            }
314:
315:            /**
316:             * Removes all key/value pairs from this Hashtable, leaving the size zero
317:             * and the capacity unchanged.
318:             * 
319:             * @see #isEmpty
320:             * @see #size
321:             */
322:            public synchronized void clear() {
323:                elementCount = 0;
324:                Arrays.fill(elementData, null);
325:                modCount++;
326:            }
327:
328:            /**
329:             * Answers a new Hashtable with the same key/value pairs, capacity and load
330:             * factor.
331:             * 
332:             * @return a shallow copy of this Hashtable
333:             * 
334:             * @see java.lang.Cloneable
335:             */
336:            @Override
337:            @SuppressWarnings("unchecked")
338:            public synchronized Object clone() {
339:                try {
340:                    Hashtable<K, V> hashtable = (Hashtable<K, V>) super .clone();
341:                    hashtable.elementData = elementData.clone();
342:                    Entry<K, V> entry;
343:                    for (int i = elementData.length; --i >= 0;) {
344:                        if ((entry = elementData[i]) != null) {
345:                            hashtable.elementData[i] = (Entry<K, V>) entry
346:                                    .clone();
347:                        }
348:                    }
349:                    return hashtable;
350:                } catch (CloneNotSupportedException e) {
351:                    return null;
352:                }
353:            }
354:
355:            private void computeMaxSize() {
356:                threshold = (int) (elementData.length * loadFactor);
357:            }
358:
359:            /**
360:             * Answers if this Hashtable contains the specified object as the value of
361:             * at least one of the key/value pairs.
362:             * 
363:             * @param value
364:             *            the object to look for as a value in this Hashtable
365:             * @return true if object is a value in this Hashtable, false otherwise
366:             * 
367:             * @see #containsKey
368:             * @see java.lang.Object#equals
369:             */
370:            public synchronized boolean contains(Object value) {
371:                if (value == null) {
372:                    throw new NullPointerException();
373:                }
374:
375:                for (int i = elementData.length; --i >= 0;) {
376:                    Entry<K, V> entry = elementData[i];
377:                    while (entry != null) {
378:                        if (entry.value.equals(value)) {
379:                            return true;
380:                        }
381:                        entry = entry.next;
382:                    }
383:                }
384:                return false;
385:            }
386:
387:            /**
388:             * Answers if this Hashtable contains the specified object as a key of one
389:             * of the key/value pairs.
390:             * 
391:             * @param key
392:             *            the object to look for as a key in this Hashtable
393:             * @return true if object is a key in this Hashtable, false otherwise
394:             * 
395:             * @see #contains
396:             * @see java.lang.Object#equals
397:             */
398:            public synchronized boolean containsKey(Object key) {
399:                return getEntry(key) != null;
400:            }
401:
402:            /**
403:             * Searches this Hashtable for the specified value.
404:             * 
405:             * @param value
406:             *            the object to search for
407:             * @return true if <code>value</code> is a value of this Hashtable, false
408:             *         otherwise
409:             */
410:            public boolean containsValue(Object value) {
411:                return contains(value);
412:            }
413:
414:            /**
415:             * Answers an Enumeration on the values of this Hashtable. The results of
416:             * the Enumeration may be affected if the contents of this Hashtable are
417:             * modified.
418:             * 
419:             * @return an Enumeration of the values of this Hashtable
420:             * 
421:             * @see #keys
422:             * @see #size
423:             * @see Enumeration
424:             */
425:            @Override
426:            @SuppressWarnings("unchecked")
427:            public synchronized Enumeration<V> elements() {
428:                if (elementCount == 0) {
429:                    return (Enumeration<V>) EMPTY_ENUMERATION;
430:                }
431:                return new HashEnumerator<V>(false);
432:            }
433:
434:            /**
435:             * Answers a Set of the mappings contained in this Hashtable. Each element
436:             * in the set is a Map.Entry. The set is backed by this Hashtable so changes
437:             * to one are reflected by the other. The set does not support adding.
438:             * 
439:             * @return a Set of the mappings
440:             */
441:            public Set<Map.Entry<K, V>> entrySet() {
442:                return new Collections.SynchronizedSet<Map.Entry<K, V>>(
443:                        new AbstractSet<Map.Entry<K, V>>() {
444:                            @Override
445:                            public int size() {
446:                                return elementCount;
447:                            }
448:
449:                            @Override
450:                            public void clear() {
451:                                Hashtable.this .clear();
452:                            }
453:
454:                            @Override
455:                            @SuppressWarnings("unchecked")
456:                            public boolean remove(Object object) {
457:                                if (contains(object)) {
458:                                    Hashtable.this 
459:                                            .remove(((Map.Entry<K, V>) object)
460:                                                    .getKey());
461:                                    return true;
462:                                }
463:                                return false;
464:                            }
465:
466:                            @Override
467:                            @SuppressWarnings("unchecked")
468:                            public boolean contains(Object object) {
469:                                Entry<K, V> entry = getEntry(((Map.Entry<K, V>) object)
470:                                        .getKey());
471:                                return object.equals(entry);
472:                            }
473:
474:                            @Override
475:                            public Iterator<Map.Entry<K, V>> iterator() {
476:                                return new HashIterator<Map.Entry<K, V>>(
477:                                        new MapEntry.Type<Map.Entry<K, V>, K, V>() {
478:                                            public Map.Entry<K, V> get(
479:                                                    MapEntry<K, V> entry) {
480:                                                return entry;
481:                                            }
482:                                        });
483:                            }
484:                        }, this );
485:            }
486:
487:            /**
488:             * Compares the specified object to this Hashtable and answer if they are
489:             * equal. The object must be an instance of Map and contain the same
490:             * key/value pairs.
491:             * 
492:             * @param object
493:             *            the object to compare with this object
494:             * @return true if the specified object is equal to this Map, false
495:             *         otherwise
496:             * 
497:             * @see #hashCode
498:             */
499:            @Override
500:            public synchronized boolean equals(Object object) {
501:                if (this  == object) {
502:                    return true;
503:                }
504:                if (object instanceof  Map) {
505:                    Map<?, ?> map = (Map<?, ?>) object;
506:                    if (size() != map.size()) {
507:                        return false;
508:                    }
509:
510:                    Set<Map.Entry<K, V>> entries = entrySet();
511:                    for (Map.Entry<?, ?> e : map.entrySet()) {
512:                        if (!entries.contains(e)) {
513:                            return false;
514:                        }
515:                    }
516:                    return true;
517:                }
518:                return false;
519:            }
520:
521:            /**
522:             * Answers the value associated with the specified key in this Hashtable.
523:             * 
524:             * @param key
525:             *            the key of the value returned
526:             * @return the value associated with the specified key, null if the
527:             *         specified key does not exist
528:             * 
529:             * @see #put
530:             */
531:            @Override
532:            public synchronized V get(Object key) {
533:                int hash = key.hashCode();
534:                int index = (hash & 0x7FFFFFFF) % elementData.length;
535:                Entry<K, V> entry = elementData[index];
536:                while (entry != null) {
537:                    if (entry.equalsKey(key, hash)) {
538:                        return entry.value;
539:                    }
540:                    entry = entry.next;
541:                }
542:                return null;
543:            }
544:
545:            Entry<K, V> getEntry(Object key) {
546:                int hash = key.hashCode();
547:                int index = (hash & 0x7FFFFFFF) % elementData.length;
548:                Entry<K, V> entry = elementData[index];
549:                while (entry != null) {
550:                    if (entry.equalsKey(key, hash)) {
551:                        return entry;
552:                    }
553:                    entry = entry.next;
554:                }
555:                return null;
556:            }
557:
558:            /**
559:             * Answers an integer hash code for the receiver. Objects which are equal
560:             * answer the same value for this method.
561:             * 
562:             * @return the receiver's hash
563:             * 
564:             * @see #equals
565:             */
566:            @Override
567:            public synchronized int hashCode() {
568:                int result = 0;
569:                Iterator<Map.Entry<K, V>> it = entrySet().iterator();
570:                while (it.hasNext()) {
571:                    Map.Entry<K, V> entry = it.next();
572:                    Object key = entry.getKey();
573:                    Object value = entry.getValue();
574:                    int hash = (key != this  ? key.hashCode() : 0)
575:                            ^ (value != this  ? (value != null ? value
576:                                    .hashCode() : 0) : 0);
577:                    result += hash;
578:                }
579:                return result;
580:            }
581:
582:            /**
583:             * Answers if this Hashtable has no key/value pairs, a size of zero.
584:             * 
585:             * @return true if this Hashtable has no key/value pairs, false otherwise
586:             * 
587:             * @see #size
588:             */
589:            @Override
590:            public synchronized boolean isEmpty() {
591:                return elementCount == 0;
592:            }
593:
594:            /**
595:             * Answers an Enumeration on the keys of this Hashtable. The results of the
596:             * Enumeration may be affected if the contents of this Hashtable are
597:             * modified.
598:             * 
599:             * @return an Enumeration of the keys of this Hashtable
600:             * 
601:             * @see #elements
602:             * @see #size
603:             * @see Enumeration
604:             */
605:            @Override
606:            @SuppressWarnings("unchecked")
607:            public synchronized Enumeration<K> keys() {
608:                if (elementCount == 0) {
609:                    return (Enumeration<K>) EMPTY_ENUMERATION;
610:                }
611:                return new HashEnumerator<K>(true);
612:            }
613:
614:            /**
615:             * Answers a Set of the keys contained in this Hashtable. The set is backed
616:             * by this Hashtable so changes to one are reflected by the other. The set
617:             * does not support adding.
618:             * 
619:             * @return a Set of the keys
620:             */
621:            public Set<K> keySet() {
622:                return new Collections.SynchronizedSet<K>(new AbstractSet<K>() {
623:                    @Override
624:                    public boolean contains(Object object) {
625:                        return containsKey(object);
626:                    }
627:
628:                    @Override
629:                    public int size() {
630:                        return elementCount;
631:                    }
632:
633:                    @Override
634:                    public void clear() {
635:                        Hashtable.this .clear();
636:                    }
637:
638:                    @Override
639:                    public boolean remove(Object key) {
640:                        if (containsKey(key)) {
641:                            Hashtable.this .remove(key);
642:                            return true;
643:                        }
644:                        return false;
645:                    }
646:
647:                    @Override
648:                    public Iterator<K> iterator() {
649:                        return new HashIterator<K>(
650:                                new MapEntry.Type<K, K, V>() {
651:                                    public K get(MapEntry<K, V> entry) {
652:                                        return entry.key;
653:                                    }
654:                                });
655:                    }
656:                }, this );
657:            }
658:
659:            /**
660:             * Associate the specified value with the specified key in this Hashtable.
661:             * If the key already exists, the old value is replaced. The key and value
662:             * cannot be null.
663:             * 
664:             * @param key
665:             *            the key to add
666:             * @param value
667:             *            the value to add
668:             * @return the old value associated with the specified key, null if the key
669:             *         did not exist
670:             * 
671:             * @see #elements
672:             * @see #get
673:             * @see #keys
674:             * @see java.lang.Object#equals
675:             */
676:            @Override
677:            public synchronized V put(K key, V value) {
678:                if (key != null && value != null) {
679:                    int hash = key.hashCode();
680:                    int index = (hash & 0x7FFFFFFF) % elementData.length;
681:                    Entry<K, V> entry = elementData[index];
682:                    while (entry != null && !entry.equalsKey(key, hash)) {
683:                        entry = entry.next;
684:                    }
685:                    if (entry == null) {
686:                        modCount++;
687:                        if (++elementCount > threshold) {
688:                            rehash();
689:                            index = (hash & 0x7FFFFFFF) % elementData.length;
690:                        }
691:                        if (index < firstSlot) {
692:                            firstSlot = index;
693:                        }
694:                        if (index > lastSlot) {
695:                            lastSlot = index;
696:                        }
697:                        entry = newEntry(key, value, hash);
698:                        entry.next = elementData[index];
699:                        elementData[index] = entry;
700:                        return null;
701:                    }
702:                    V result = entry.value;
703:                    entry.value = value;
704:                    return result;
705:                }
706:                throw new NullPointerException();
707:            }
708:
709:            /**
710:             * Copies every mapping in the specified Map to this Hashtable.
711:             * 
712:             * @param map
713:             *            the Map to copy mappings from
714:             */
715:            public synchronized void putAll(Map<? extends K, ? extends V> map) {
716:                for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
717:                    put(entry.getKey(), entry.getValue());
718:                }
719:            }
720:
721:            /**
722:             * Increases the capacity of this Hashtable. This method is sent when the
723:             * size of this Hashtable exceeds the load factor.
724:             */
725:            protected void rehash() {
726:                int length = (elementData.length << 1) + 1;
727:                if (length == 0) {
728:                    length = 1;
729:                }
730:                int newFirst = length;
731:                int newLast = -1;
732:                Entry<K, V>[] newData = newElementArray(length);
733:                for (int i = lastSlot + 1; --i >= firstSlot;) {
734:                    Entry<K, V> entry = elementData[i];
735:                    while (entry != null) {
736:                        int index = (entry.getKeyHash() & 0x7FFFFFFF) % length;
737:                        if (index < newFirst) {
738:                            newFirst = index;
739:                        }
740:                        if (index > newLast) {
741:                            newLast = index;
742:                        }
743:                        Entry<K, V> next = entry.next;
744:                        entry.next = newData[index];
745:                        newData[index] = entry;
746:                        entry = next;
747:                    }
748:                }
749:                firstSlot = newFirst;
750:                lastSlot = newLast;
751:                elementData = newData;
752:                computeMaxSize();
753:            }
754:
755:            /**
756:             * Remove the key/value pair with the specified key from this Hashtable.
757:             * 
758:             * @param key
759:             *            the key to remove
760:             * @return the value associated with the specified key, null if the
761:             *         specified key did not exist
762:             * 
763:             * @see #get
764:             * @see #put
765:             */
766:            @Override
767:            public synchronized V remove(Object key) {
768:                int hash = key.hashCode();
769:                int index = (hash & 0x7FFFFFFF) % elementData.length;
770:                Entry<K, V> last = null;
771:                Entry<K, V> entry = elementData[index];
772:                while (entry != null && !entry.equalsKey(key, hash)) {
773:                    last = entry;
774:                    entry = entry.next;
775:                }
776:                if (entry != null) {
777:                    modCount++;
778:                    if (last == null) {
779:                        elementData[index] = entry.next;
780:                    } else {
781:                        last.next = entry.next;
782:                    }
783:                    elementCount--;
784:                    V result = entry.value;
785:                    entry.value = null;
786:                    return result;
787:                }
788:                return null;
789:            }
790:
791:            /**
792:             * Answers the number of key/value pairs in this Hashtable.
793:             * 
794:             * @return the number of key/value pairs in this Hashtable
795:             * 
796:             * @see #elements
797:             * @see #keys
798:             */
799:            @Override
800:            public synchronized int size() {
801:                return elementCount;
802:            }
803:
804:            /**
805:             * Answers the string representation of this Hashtable.
806:             * 
807:             * @return the string representation of this Hashtable
808:             */
809:            @Override
810:            public synchronized String toString() {
811:                if (isEmpty()) {
812:                    return "{}"; //$NON-NLS-1$
813:                }
814:
815:                StringBuilder buffer = new StringBuilder(size() * 28);
816:                buffer.append('{');
817:                for (int i = lastSlot; i >= firstSlot; i--) {
818:                    Entry<K, V> entry = elementData[i];
819:                    while (entry != null) {
820:                        if (entry.key != this ) {
821:                            buffer.append(entry.key);
822:                        } else {
823:                            // luni.04=this Map
824:                            buffer
825:                                    .append("(" + Messages.getString("luni.04") + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
826:                        }
827:                        buffer.append('=');
828:                        if (entry.value != this ) {
829:                            buffer.append(entry.value);
830:                        } else {
831:                            // luni.04=this Map
832:                            buffer
833:                                    .append("(" + Messages.getString("luni.04") + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
834:                        }
835:                        buffer.append(", "); //$NON-NLS-1$
836:                        entry = entry.next;
837:                    }
838:                }
839:                // Remove the last ", "
840:                if (elementCount > 0) {
841:                    buffer.setLength(buffer.length() - 2);
842:                }
843:                buffer.append('}');
844:                return buffer.toString();
845:            }
846:
847:            /**
848:             * Answers a Collection of the values contained in this Hashtable. The
849:             * collection is backed by this Hashtable so changes to one are reflected by
850:             * the other. The collection does not support adding.
851:             * 
852:             * @return a Collection of the values
853:             */
854:            public Collection<V> values() {
855:                return new Collections.SynchronizedCollection<V>(
856:                        new AbstractCollection<V>() {
857:                            @Override
858:                            public boolean contains(Object object) {
859:                                return Hashtable.this .contains(object);
860:                            }
861:
862:                            @Override
863:                            public int size() {
864:                                return elementCount;
865:                            }
866:
867:                            @Override
868:                            public void clear() {
869:                                Hashtable.this .clear();
870:                            }
871:
872:                            @Override
873:                            public Iterator<V> iterator() {
874:                                return new HashIterator<V>(
875:                                        new MapEntry.Type<V, K, V>() {
876:                                            public V get(MapEntry<K, V> entry) {
877:                                                return entry.value;
878:                                            }
879:                                        });
880:                            }
881:                        }, this );
882:            }
883:
884:            private synchronized void writeObject(ObjectOutputStream stream)
885:                    throws IOException {
886:                stream.defaultWriteObject();
887:                stream.writeInt(elementData.length);
888:                stream.writeInt(elementCount);
889:                for (int i = elementData.length; --i >= 0;) {
890:                    Entry<K, V> entry = elementData[i];
891:                    while (entry != null) {
892:                        stream.writeObject(entry.key);
893:                        stream.writeObject(entry.value);
894:                        entry = entry.next;
895:                    }
896:                }
897:            }
898:
899:            @SuppressWarnings("unchecked")
900:            private void readObject(ObjectInputStream stream)
901:                    throws IOException, ClassNotFoundException {
902:                stream.defaultReadObject();
903:                int length = stream.readInt();
904:                elementData = newElementArray(length);
905:                elementCount = stream.readInt();
906:                for (int i = elementCount; --i >= 0;) {
907:                    Object key = stream.readObject();
908:                    int hash = key.hashCode();
909:                    int index = (hash & 0x7FFFFFFF) % length;
910:                    if (index < firstSlot) {
911:                        firstSlot = index;
912:                    }
913:                    if (index > lastSlot) {
914:                        lastSlot = index;
915:                    }
916:                    Entry<K, V> entry = newEntry((K) key, (V) stream
917:                            .readObject(), hash);
918:                    entry.next = elementData[index];
919:                    elementData[index] = entry;
920:                }
921:            }
922:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.