Dictionaries
Dictionary Syntax and Semantics
A dictionary is a mapping from a key type to a value type.
For example:
module M
{
struct Employee
{
long number;
string firstName;
string lastName;
}
dictionary<long, Employee> EmployeeMap;
}
This definition creates a dictionary named EmployeeMap that maps from an employee number to a structure containing the details for an employee. Whether or not the key type (the employee number, of type long in this example) is also part of the value type (the Employee structure in this example) is up to you — as far as Slice is concerned, there is no need to include the key as part of the value.
Dictionaries can be used to implement sparse arrays, or any lookup data structure with non-integral key type. Even though a sequence of structures containing key-value pairs could be used to model the same thing, a dictionary is more appropriate:
A dictionary clearly signals the intent of the designer, namely, to provide a mapping from a domain of values to a range of values. (A sequence of structures of key-value pairs does not signal that same intent as clearly.)
At the programming language level, sequences are implemented as vectors (or possibly lists), that is, they are not well suited to model sparsely populated domains and require a linear search to locate an element with a particular value. On the other hand, dictionaries are implemented as a data structure (typically a hash table or red-black tree) that supports efficient searching in O(log n) average time or better.
Allowable Types for Dictionary Keys and Values
The key type of a dictionary need not be an integral type. For example, we could use the following definition to translate the names of the days of the week:
dictionary<string, string> WeekdaysEnglishToGerman;
The server implementation would take care of initializing this map with the key-value pairs Monday-Montag, Tuesday-Dienstag, and so on.
The value type of a dictionary can be any Slice type. However, the key type of a dictionary is limited to one of the following types:
Integral types (
short,int,long)Structures containing only data members of legal key types
Other complex types, such as dictionaries, and floating-point types (float and double) cannot be used as the key type. Complex types are disallowed because they complicate the language mappings for dictionaries, and floating-point types are disallowed because representational changes of values as they cross machine boundaries can lead to ill-defined semantics for equality.
Language Mapping
Default Mapping
Here is the definition of our EmployeeMap once more:
dictionary<long, Employee> EmployeeMap;
As for sequences, the Java mapping does not create a separate named type for this definition. Instead, the dictionary is simply an instance of the generic type java.util.Map<K, V>, where K is the mapping of the key type and V is the mapping of the value type. In the example above, EmployeeMap is mapped to the Java type java.util.Map<Long, Employee>. The following code demonstrates how to allocate and use an instance of EmployeeMap:
var em = new java.util.HashMap<Long, Employee>();
Employee e = new Employee();
e.number = 31;
e.firstName = "James";
e.lastName = "Gosling";
em.put(e.number, e);
Custom Mapping for Dictionaries
If the semantics of a HashMap are not suitable for your application, you can specify an alternate type using the java:type metadata directive as shown in the example below:
["java:type:java.util.TreeMap<String, String>"]
dictionary<string, string> StringMap;
It is your responsibility to use type parameters for the Java class (String in the example above) that are the correct mappings for the dictionary's key and value types.
The compiler requires the formal type to implement java.util.Map<K, V>. If you do not specify a formal type, the compiler uses this type by default.
Note that extra care must be taken when defining dictionary types that contain nested generic types, such as a dictionary whose element type is a custom sequence. The Java compiler strictly enforces type safety, therefore any compatibility issues in the custom type metadata will be apparent when the generated code is compiled.
Refer to the Sequences | Customizing-the-Sequence-Mapping-with-java:type for more information about java:type.