Hash map collections in object-oriented ABL
- Last Updated: March 27, 2023
- 6 minute read
- OpenEdge
- Version 13.0
- Documentation
A hash map is a data structure that uses a hash function to map keys to their associated values. A hash map consists of key-value pairs. The keys in a hash map must be unique, but the values do not have to be. A simple example of a hash map is a collection of employees (keys) and their managers (values). Each employee is unique, but employees can have the same manager. The ordering of elements in a hash map is not important. Hash maps are efficient, and allow faster access to elements than other types of collections.
OpenEdge provides a built-in HashMap collection data structure
in the Progress.Collections framework. This diagram
shows the classes and interfaces relevant to a HashMap.
This table describes the classes and interfaces for HashMap.
(For collection-specific interfaces, see Collections in object-oriented ABL.)
| Class or interface | Description |
|---|---|
| Progress.Collections.HashMap<K,V> class | Represents a strongly-typed collection of key-value pairs (map) backed by a hash table. |
| Progress.Collections.HashMapIterator<K,V> class | Represents the type of the object returned by the
GetIterator() method in a HashMap<K,V>
object, allowing traversal of the elements in the
HashMap. |
| Progress.Collections.IEqualityComparer<T> interface | Provides an alternate implementation of HashCode() and
Equals() to the map collection object. |
| Progress.Collections.IHashable interface | Provides the implementation for generating the hash code and is also capable of identifying when a key is considered the same. |
| Progress.Collections.IMap<K,V> interface | The root interface for map collection classes. |
| Progress.Collections.KeySet<K> class | Class used by the Keys property of the HashMap to
return a set containing all the keys in the HashMap
instance. |
| Progress.Collections.KeySetIterator<K> class | Represents the type of the object returned by the GetIterator() method
in a KeySet<K> class, allowing traversal of the elements
in the KeySet<K>. |
| Progress.Collections.KeyValuePair<K,V> class | A class that holds a key-value pair for a Map collection. |
How HashMap works
A HashMap relies on a hash function to compute an index (hash code) into an
array of buckets, from which the desired value can be found. During lookup, the key
is hashed, and the resulting hash indicates in which bucket the corresponding value
is stored. The HashMap is able to hold keys and values as
object-oriented types (that is, compatible with
Progress.Lang.Object). Scalar types are not supported. To
ensure keys are unique, you must define how to determine when the objects used as
keys are considered to be equal.
HashMap are:- Identify when a key is already in the collection, that is, compare the keys for equality.
- Generate a hash code for the key.
HashMap enforces these requirements via an equality
comparer. It provides a default equality comparer, which
requires that the key object implement the IHashable interface.
IHashable defines methods for getting the hash code for the key
(HashCode() method), and for determining if two keys are the
same (Equals() method). For cases where the class used for the key
cannot be changed or may not provide the desired behavior, you can define a
custom equality comparer. To define a custom equality comparer, you
use a class that implements the IEqualityComparer<T>
interface. This interface also provides methods for getting the hash code and for
determining if two keys are the same. You can specify an instance of a custom
equality comparer when a new instance of the HashMap is
created.The HashMap is responsible for maintaining the uniqueness of the keys in the
collection, but it does not define the uniqueness of the key. That job is the
responsibility of the hashable object (that is, the key object that implements
IHashable), or the custom equality comparer, and any issues in
those components impact the ability of the HashMap to enforce
uniqueness.
OpenEdge provides a built-in HASH-CODE function, which you can use in your
HashCode() implementation, to return a hash code. This function
is intended to be used with HashMaps.
The KeyValuePair<K,V> class is used to represent the
collection of key-value pairs. When you iterate through the
HashMap, you get instances of
KeyValuePair<K,V>, which are the elements of the
collection.
HashMap implementation:- Supports any object-oriented ABL object, including .NET objects. However, you must specify
a custom equality comparer (by implementing the
IEqualityComparer<T>interface) when adding .NET objects to aHashMap. - Duplicate keys are not allowed. This is dependent on the equality comparer
implementation (whether using the default or a custom one). If the
Equals()method returns TRUE, a key object is considered to be in the map already, and is not added again, that is, the existing key-value pair remains in the map. - The map does not guarantee any ordering for the key-value pairs, and there is no guarantee the order will remain constant over time (due to rehashing).
- All the methods that take a key as a parameter determine the hash code and equality of the key based on the equality comparer implementation (whether using the default or a custom one).
- The
HashMaphas a reference to any key and value objects added to it, and that prevents garbage collection of such added objects until the reference no longer exists. - Changing the key object's value of an existing element is not supported and may lead to undefined behavior (that is, the uniqueness of the map is not guaranteed).
- It is not safe to delete key objects that are in the
HashMap. Doing so potentially invalidates the complete collection as it may no longer be able to guarantee consistency or uniqueness of theHashMap. - If a deleted object reference is encountered during any operation that needs to access
properties of the element or invoke a method on that element, the operation
fails, and an error is raised indicating that a deleted object reference was
encountered. That includes the equality comparer object, if one was
specified for the
HashMap.
Serialization and remote parameter passing
A HashMap object can be serialized using the present forms of
serialization, which include binary and JSON serialization, via the built-in Progress.IO.BinarySerializer and Progress.IO.JsonSerializer classes, respectively.
You can also pass such objects to, or from, a Progress Application Server (PAS) for OpenEdge remote call, if both sides are running version 12.7.
Serialization and remote parameter passing for object-oriented ABL objects
require that all objects are marked as SERIALIZABLE. Therefore, the objects inside the collection also need to be
SERIALIZABLE, which includes the key and value
objects in the collection, otherwise an error is raised during object serialization.
This includes the equality comparer object, if one is specified when the
HashMap object was created. That means that if the equality
comparer object is not serializable, you cannot serialize the
HashMap object either.
Example: HashMap collection
HashMap. The example uses an Employee class
(shown) and assumes a class called Manager (not shown).| Employee.cls |
|---|
|
|