PrevNextUpHome SophiaFramework UNIVERSE 5.3

13.5. Hashmap

SFXLinkedHashMap and SFXFlatHashMap are data structures for operating the hashmap with the multiple of the key-value pair elements.

The SFXLinkedHashMap class internally contains the two-way linked list where the pair elements are linked in the insertion order.

In the SFXFlatHashMap class, there is no two-way linked list of the pair elements.

Depending on whether or not the two-way linked list exists, the SFXLinkedHashMap class and the SFXFlatHashMap class have the characteristics in the table below.

Table 13.2. SFXLinkedHashMap and SFXFlatHashMap

Item Description
Traversing elements using the iterator or the enumerator SFXLinkedHashMap is faster since the two-way linked list is available.
Comparing two hashmaps SFXLinkedHashMap is faster since the two-way linked list is available.
Adding or removing elements, or clearing the hashmap SFXFlatHashMap is faster since there is no need to maintain the two-way linked list.

The code below is to define the SFXLinkedHashMap hashmap with data of (key: SFXAnsiString type, value: SInt32 type) as the key-value pair elements.

// define hashmap with data of (key: SFXAnsiString type, value: SInt32 type) as the key-value pair elements
// * SFXAnsiString / SFXWideString can be used in hashmap as key. 
SFXLinkedHashMap<SFXAnsiString, SInt32> hashmap;
// in case of SFXFlatHashMap hashmap:
// SFXFlatHashMap<SFXAnsiString, SInt32> hashmap;

// current status: hashmap = []
[Tip] Tip
In the SFXLinkedHashMap / SFXFlatHashMap hashmap, the SFXAnsiString / SFXWideString string can be set as the key of the pair element.

The code below is to add the key-value pair elements into the hashmap with the SFXLinkedHashMap::Set / SFXFlatHashMap::Set function.

// current status: hashmap = []

hashmap.Set("abc", 7);
// current status: hashmap = [("abc", 7)]

hashmap.Set("def", 15);
// current status: hashmap = [("abc", 7), ("def", 15)]

SFXAnsiString str1("ghi");
SFXAnsiString str2("jkl");
SFXAnsiString str3("mno");

hashmap.Set(str1, 31);
// current status: hashmap = [("abc", 7), ("def", 15), ("ghi", 31)]

hashmap.Set(str2, 45);
// current status: hashmap = [("abc", 7), ("def", 15), ("ghi", 31), ("jkl", 45)]

hashmap.Set(str3, 51);
// current status: hashmap = [("abc", 7), ("def", 15), ("ghi", 31), ("jkl", 45), ("mno", 51)]

To get the value of the pair element with the specified key, call the SFXLinkedHashMap::Get / SFXFlatHashMap::Get function.

// current status: hashmap = [("abc", 7), ("def", 15), ("ghi", 31), ("jkl", 45), ("mno", 51)]
SInt32 n = hashmap.Get("def"); // n = 15
[Caution] Caution
If there is no pair element with the specified key, the SFXLinkedHashMap::Get / SFXFlatHashMap::Get function will return 0 or null depending on the type of the value.

Pair elements of the hashmap can be traversed using the key/value iterator or the the key/value enumurator. Since the SFXLinkedHashMap class contains the two-way linked list, elements will be traversed faster than the SFXFlatHashMap class.

Example 13.6. Traversing elements using the key iterator

// current status: hashmap = [("abc", 7), ("def", 15), ("ghi", 31), ("jkl", 45), ("mno", 51)]

// get the key iterator
SFXLinkedHashMap<SFXAnsiString, SInt32>::KeyIterator k_iterator = hashmap.GetFirstKeyIterator();
// in case of the SFXFlatHashMap hashmap: 
// SFXFlatHashMap<SFXAnsiString, SInt32>::KeyIterator k_iterator = hashmap.GetKeyIterator();

while(k_iterator.HasNext()) {

    SFXAnsiString key = k_iterator.GetNext(); // get the key

    // display the key-value pair
    TRACE("Key: %s, Value: %d", key.GetCString(), hashmap.Get(key));
}

After executing the above code, the following contents will be displayed in the BREW Output Window.

// in case of SFXLinkedHashMap
*dbgprintf*:0 - Key: abc, Value: 7
*dbgprintf*:0 - Key: def, Value: 15
*dbgprintf*:0 - Key: ghi, Value: 31
*dbgprintf*:0 - Key: jkl, Value: 45
*dbgprintf*:0 - Key: mno, Value: 51

// in case of SFXFlatHashMap
*dbgprintf*:0 - Key: abc, Value: 7
*dbgprintf*:0 - Key: jkl, Value: 45
*dbgprintf*:0 - Key: def, Value: 15
*dbgprintf*:0 - Key: mno, Value: 51
*dbgprintf*:0 - Key: ghi, Value: 31
[Note] Note

In case of SFXLinkedHashMap, the key-value elements are displayed in the insertion order. On the other hand, in case of SFXFlatHashMap, they are not displayed in the insertion order.

To process a data structure bigger than 4 bytes as an element, store its pointer as follows:

// data type to store into the value of the pair element of the hashmap(actually, a pointer to this will be stored)
SFMTYPEDEFSTRUCT(Address)
struct Address {
    ACharPtr zip;
    ACharPtr prefecture;
    ACharPtr city;
    Address(ACharPtr zip, ACharPtr prefecture, ACharPtr city) 
        : zip(zip), prefecture(prefecture), city(city) {}
};

AddressPtr pAddr;

// make a hashmap
SFXLinkedHashMap<SFXAnsiString, AddressPtr> hashmap;

pAddr = new Address("102-0072", "Tokyo", "Chiyoda-ku");
hashmap.Set("Yamada", pAddr);
pAddr = new Address("606-8203", "Kyoto", "Kyoto-shi");
hashmap.Set("Suzuki", pAddr);
pAddr = new Address("060-0000", "Hokkaido", "Sapporo-shi");
hashmap.Set("Satou", pAddr);

// display the number of the pair elements of the hashmap
TRACE("HashMap count = %d", hashmap.GetSize());

// get the key iterator of the hashmap
SFXLinkedHashMap<SFXAnsiString, AddressPtr>::KeyIterator k_iterator = hashmap.GetFirstKeyIterator();

while(k_iterator.HasNext()) {

    SFXAnsiString name = k_iterator.GetNext(); // get the key of the pair element

    pAddr = (AddressPtr) hashmap.Get(name);

    // display the pair element of the hashmap
    TRACE("Name = %s, Zip = %s, Prefecture = %s, City = %s", name.GetCString(), pAddr->zip, pAddr->prefecture, pAddr->city);
}

// get the value iterator of the hashmap
SFXLinkedHashMap<SFXAnsiString, AddressPtr>::ValueIterator v_iterator = hashmap.GetFirstValueIterator();

while(v_iterator.HasNext()) {

    pAddr = v_iterator.GetNext(); // get the value of the pair element

    delete pAddr;  // release the memory area which the pointer, the value of the pair element, points to
}

// clear hashmap(SFXAnsiString strings, the keys of the pair elements, will be released automatically)
hashmap.Clear();
[Note] Note

In case of data bigger than 4 bytes, store its pointer into the value of the pair element. When the hashmap is cleared, the memory area which the pointer points to will not be automatically released. As in the above code, just before it is cleared, it is necessary to explicitly release the memory area which the pointer points to using the delete statement. Otherwise, memory leakage will occur.

The SFXAnsiString string stored into the key of the pair element will be released automatically when the pair element is removed.

After executing the above code, the following contents will be displayed in the BREW Output Window.

*dbgprintf*:0 - HashMap count = 3
*dbgprintf*:0 - Name = Yamada, Zip = 102-0072, Prefecture = Tokyo, City = Chiyoda-ku
*dbgprintf*:0 - Name = Suzuki, Zip = 606-8203, Prefecture = Kyoto, City = Kyoto-shi
*dbgprintf*:0 - Name = Satou, Zip = 060-0000, Prefecture = Hokkaido, City = Sapporo-shi