Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A [Map] is an associative container, mapping a key to a value. | 8 * A [Map] is an associative container, mapping a key to a value. |
| 9 * Null values are supported, but null keys are not. | 9 * Null values are supported, but null keys are not. |
| 10 */ | 10 */ |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 * Removes all pairs from the map. | 62 * Removes all pairs from the map. |
| 63 */ | 63 */ |
| 64 void clear(); | 64 void clear(); |
| 65 | 65 |
| 66 /** | 66 /** |
| 67 * Applies [f] to each {key, value} pair of the map. | 67 * Applies [f] to each {key, value} pair of the map. |
| 68 */ | 68 */ |
| 69 void forEach(void f(K key, V value)); | 69 void forEach(void f(K key, V value)); |
| 70 | 70 |
| 71 /** | 71 /** |
| 72 * Returns a collection containing all the keys in the map. | 72 * The keys of [this]. |
| 73 */ | 73 */ |
| 74 Collection<K> get keys; | 74 Iterable<K> get keys; |
|
Lasse Reichstein Nielsen
2012/12/22 22:09:24
You can make it (unmodifiable) Set<K>, and it woul
floitsch
2013/01/03 13:35:41
contains is actually in Iterable, so apparently a
| |
| 75 | 75 |
| 76 /** | 76 /** |
| 77 * Returns a collection containing all the values in the map. | 77 * The values of [this]. |
| 78 */ | 78 */ |
| 79 Collection<V> get values; | 79 Iterable<V> get values; |
| 80 | 80 |
| 81 /** | 81 /** |
| 82 * The number of {key, value} pairs in the map. | 82 * The number of {key, value} pairs in the map. |
| 83 */ | 83 */ |
| 84 int get length; | 84 int get length; |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * Returns true if there is no {key, value} pair in the map. | 87 * Returns true if there is no {key, value} pair in the map. |
| 88 */ | 88 */ |
| 89 bool get isEmpty; | 89 bool get isEmpty; |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 | 344 |
| 345 bool get isEmpty { | 345 bool get isEmpty { |
| 346 return _numberOfEntries == 0; | 346 return _numberOfEntries == 0; |
| 347 } | 347 } |
| 348 | 348 |
| 349 int get length { | 349 int get length { |
| 350 return _numberOfEntries; | 350 return _numberOfEntries; |
| 351 } | 351 } |
| 352 | 352 |
| 353 void forEach(void f(K key, V value)) { | 353 void forEach(void f(K key, V value)) { |
| 354 int length = _keys.length; | 354 Iterator<int> it = new _HashMapImplIndexIterator(this); |
| 355 for (int i = 0; i < length; i++) { | 355 while (it.moveNext()) { |
| 356 var key = _keys[i]; | 356 f(_keys[it.current], _values[it.current]); |
| 357 if ((key != null) && (!identical(key, _DELETED_KEY))) { | |
| 358 f(key, _values[i]); | |
| 359 } | |
| 360 } | 357 } |
| 361 } | 358 } |
| 362 | 359 |
| 360 Iterable<K> get keys => new _HashMapImplKeyIterable<K>(this); | |
| 363 | 361 |
| 364 Collection<K> get keys { | 362 Iterable<V> get values => new _HashMapImplValueIterable<V>(this); |
| 365 List<K> list = new List<K>.fixedLength(length); | |
| 366 int i = 0; | |
| 367 forEach((K key, V value) { | |
| 368 list[i++] = key; | |
| 369 }); | |
| 370 return list; | |
| 371 } | |
| 372 | |
| 373 Collection<V> get values { | |
| 374 List<V> list = new List<V>.fixedLength(length); | |
| 375 int i = 0; | |
| 376 forEach((K key, V value) { | |
| 377 list[i++] = value; | |
| 378 }); | |
| 379 return list; | |
| 380 } | |
| 381 | 363 |
| 382 bool containsKey(K key) { | 364 bool containsKey(K key) { |
| 383 return (_probeForLookup(key) != -1); | 365 return (_probeForLookup(key) != -1); |
| 384 } | 366 } |
| 385 | 367 |
| 386 bool containsValue(V value) { | 368 bool containsValue(V value) => values.contains(value); |
| 387 int length = _values.length; | |
| 388 for (int i = 0; i < length; i++) { | |
| 389 var key = _keys[i]; | |
| 390 if ((key != null) && (!identical(key, _DELETED_KEY))) { | |
| 391 if (_values[i] == value) return true; | |
| 392 } | |
| 393 } | |
| 394 return false; | |
| 395 } | |
| 396 | 369 |
| 397 String toString() { | 370 String toString() { |
| 398 return Maps.mapToString(this); | 371 return Maps.mapToString(this); |
| 399 } | 372 } |
| 400 } | 373 } |
| 401 | 374 |
| 375 class _HashMapImplKeyIterable<E> extends Iterable<E> { | |
|
Lasse Reichstein Nielsen
2012/12/22 22:09:24
Extend _UnmodifiableSet (which we should have at s
floitsch
2013/01/03 13:35:41
In a future CL. but I agree.
| |
| 376 final _HashMapImpl _map; | |
| 377 _HashMapImplKeyIterable(this._map); | |
| 378 | |
| 379 Iterator<E> get iterator => new _HashMapImplKeyIterator<E>(_map); | |
| 380 } | |
| 381 | |
| 382 class _HashMapImplValueIterable<E> extends Iterable<E> { | |
| 383 final _HashMapImpl _map; | |
| 384 _HashMapImplValueIterable(this._map); | |
| 385 | |
| 386 Iterator<E> get iterator => new _HashMapImplValueIterator<E>(_map); | |
| 387 } | |
| 388 | |
| 389 abstract class _HashMapImplIterator<E> implements Iterator<E> { | |
| 390 final _HashMapImpl _map; | |
| 391 int _index = -1; | |
| 392 E _current; | |
| 393 | |
| 394 _HashMapImplIterator(this._map); | |
| 395 | |
| 396 E _computeCurrentFromIndex(int index, List keys, List values); | |
| 397 | |
| 398 bool moveNext() { | |
| 399 int length = _map._keys.length; | |
| 400 int newIndex = _index + 1; | |
| 401 while (newIndex < length) { | |
| 402 var key = _map._keys[newIndex]; | |
| 403 if ((key != null) && (!identical(key, _HashMapImpl._DELETED_KEY))) { | |
| 404 _current = _computeCurrentFromIndex(newIndex, _map._keys, _map._values); | |
| 405 _index = newIndex; | |
| 406 return true; | |
| 407 } | |
| 408 newIndex++; | |
| 409 } | |
| 410 _index = length; | |
| 411 _current = null; | |
| 412 return false; | |
| 413 } | |
| 414 | |
| 415 E get current => _current; | |
| 416 } | |
| 417 | |
| 418 class _HashMapImplKeyIterator<E> extends _HashMapImplIterator<E> { | |
| 419 _HashMapImplKeyIterator(_HashMapImpl map) : super(map); | |
| 420 | |
| 421 E _computeCurrentFromIndex(int index, List keys, List values) { | |
| 422 return keys[index]; | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 class _HashMapImplValueIterator<E> extends _HashMapImplIterator<E> { | |
| 427 _HashMapImplValueIterator(_HashMapImpl map) : super(map); | |
| 428 | |
| 429 E _computeCurrentFromIndex(int index, List keys, List values) { | |
| 430 return values[index]; | |
| 431 } | |
| 432 } | |
| 433 | |
| 434 class _HashMapImplIndexIterator extends _HashMapImplIterator<int> { | |
| 435 _HashMapImplIndexIterator(_HashMapImpl map) : super(map); | |
| 436 | |
| 437 int _computeCurrentFromIndex(int index, List keys, List values) { | |
| 438 return index; | |
| 439 } | |
| 440 } | |
| 402 | 441 |
| 403 /** | 442 /** |
| 404 * A singleton sentinel used to represent when a key is deleted from the map. | 443 * A singleton sentinel used to represent when a key is deleted from the map. |
| 405 * We can't use [: const Object() :] as a sentinel because it would end up | 444 * We can't use [: const Object() :] as a sentinel because it would end up |
| 406 * canonicalized and then we cannot distinguish the deleted key from the | 445 * canonicalized and then we cannot distinguish the deleted key from the |
| 407 * canonicalized [: Object() :]. | 446 * canonicalized [: Object() :]. |
| 408 */ | 447 */ |
| 409 class _DeletedKeySentinel { | 448 class _DeletedKeySentinel { |
| 410 const _DeletedKeySentinel(); | 449 const _DeletedKeySentinel(); |
| 411 } | 450 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 | 505 |
| 467 V putIfAbsent(K key, V ifAbsent()) { | 506 V putIfAbsent(K key, V ifAbsent()) { |
| 468 V value = this[key]; | 507 V value = this[key]; |
| 469 if ((this[key] == null) && !(containsKey(key))) { | 508 if ((this[key] == null) && !(containsKey(key))) { |
| 470 value = ifAbsent(); | 509 value = ifAbsent(); |
| 471 this[key] = value; | 510 this[key] = value; |
| 472 } | 511 } |
| 473 return value; | 512 return value; |
| 474 } | 513 } |
| 475 | 514 |
| 476 Collection<K> get keys { | 515 Iterable<K> get keys { |
| 477 List<K> list = new List<K>.fixedLength(length); | 516 return new MappedIterable<_KeyValuePair<K, V>, K>( |
| 478 int index = 0; | 517 _list, (_KeyValuePair<K, V> entry) => entry.key); |
| 479 _list.forEach((_KeyValuePair<K, V> entry) { | |
| 480 list[index++] = entry.key; | |
| 481 }); | |
| 482 assert(index == length); | |
| 483 return list; | |
| 484 } | 518 } |
| 485 | 519 |
| 486 | 520 |
| 487 Collection<V> get values { | 521 Iterable<V> get values { |
| 488 List<V> list = new List<V>.fixedLength(length); | 522 return new MappedIterable<_KeyValuePair<K, V>, V>( |
| 489 int index = 0; | 523 _list, (_KeyValuePair<K, V> entry) => entry.value); |
| 490 _list.forEach((_KeyValuePair<K, V> entry) { | |
| 491 list[index++] = entry.value; | |
| 492 }); | |
| 493 assert(index == length); | |
| 494 return list; | |
| 495 } | 524 } |
| 496 | 525 |
| 497 void forEach(void f(K key, V value)) { | 526 void forEach(void f(K key, V value)) { |
| 498 _list.forEach((_KeyValuePair<K, V> entry) { | 527 _list.forEach((_KeyValuePair<K, V> entry) { |
| 499 f(entry.key, entry.value); | 528 f(entry.key, entry.value); |
| 500 }); | 529 }); |
| 501 } | 530 } |
| 502 | 531 |
| 503 bool containsKey(K key) { | 532 bool containsKey(K key) { |
| 504 return _map.containsKey(key); | 533 return _map.containsKey(key); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 520 | 549 |
| 521 void clear() { | 550 void clear() { |
| 522 _map.clear(); | 551 _map.clear(); |
| 523 _list.clear(); | 552 _list.clear(); |
| 524 } | 553 } |
| 525 | 554 |
| 526 String toString() { | 555 String toString() { |
| 527 return Maps.mapToString(this); | 556 return Maps.mapToString(this); |
| 528 } | 557 } |
| 529 } | 558 } |
| 559 | |
| OLD | NEW |