Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkedHashMap is unable to find an existing key #55722

Closed
rebaz94 opened this issue May 14, 2024 · 5 comments
Closed

LinkedHashMap is unable to find an existing key #55722

rebaz94 opened this issue May 14, 2024 · 5 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. library-core

Comments

@rebaz94
Copy link

rebaz94 commented May 14, 2024

I've come across a bug in the map where the key exists in the map, but it can't be found.

final LinkedHashMap<String, dynamic> data = LinkedHashMap.identity();
print(data['key1']); // returns null
print(data.containsKey('key1')); // returns false
print(data.keys.contains(id)); // returns true

In this example, despite 'key1' being present in the map but it return null, and containsKey incorrectly reports its absence. However, when checking the map's entries, using keys or checking with == equality return the value

Screen.Recording.2024-05-14.at.9.33.53.PM.mp4
@lrhn
Copy link
Member

lrhn commented May 14, 2024

Edit: Ah, it was a movie, not a picture. Makes more sense now.

That does look suspicious, almost as if the hash table has been built using the wrong hash numbers.
(That said, a Map's keys.contains should work exactly the same as containsKey, so getting a different result is itself a sign of something not being correct. Quoting the keys documentation:

The returned iterable has efficient length and contains operations, based on length and containsKey of the map.

So something is off.)

@lrhn lrhn added area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. library-core labels May 14, 2024
@rebaz94
Copy link
Author

rebaz94 commented May 14, 2024

sorry for bad example, This code snippet just an example how I utilized the map. please check the video

final LinkedHashMap<String, dynamic> data = LinkedHashMap.identity();
print(data['key1']); // returns null
print(data.containsKey('key1')); // returns false
print(data.keys.contains(id)); // returns true

@mraleph
Copy link
Member

mraleph commented May 15, 2024

@rebaz94 Dart does not require String instances to be globally canonicalized (with some exceptions around compile time constants). This means two strings can be equal but not identical (because they are represented by different objects).

Simple example:

void main() {
  final s0 = 'key1';
  final s1 = 'key1,key2'.split(',').first;
  print(s0 == s1);
  print(identical(s0, s1));
}

This means using LinkedHashMap<String, ...>.identity() is not a good idea (it is a map which uses key identity rather than equality) unless you somehow ensure canonicalization (e.g. you have another Map<String, String> somewhere which stores canonical instances).

@mraleph mraleph closed this as completed May 15, 2024
@rebaz94
Copy link
Author

rebaz94 commented May 15, 2024

Ah, got it. Thank you for the clarification.

@lrhn
Copy link
Member

lrhn commented May 15, 2024

I'm still worried that .keys.contains does not answer the same as .containsKey. That suggests that .keys.contains is probably also not efficient. The documentation for keys states that it must have efficient contains (fx. backed by the map's containsKey.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. library-core
Projects
None yet
Development

No branches or pull requests

3 participants