Creating a Map
Maps store data in key/value pairs called entries, which can be one of many data types. To create a map, you just need to give it a name, then write some data to it.
To create a map, use the HazelcastInstance.getMap()
method and pass it the name that you want to call your map. If a map with this name already exists, Hazelcast returns that map. Otherwise, Hazelcast creates a new map with the given name.
After creating a map, you can write data to it. The simplest way is the map.put()
method, which we will use in the following examples. This method takes a key and a value.
In this example, we create a map called capitals
, which stores the names of capital cities as strings. The key is a unique integer for each entry.
Map<Integer, String> capitalcities = hzClient.getMap( "capitals" );
capitalcities.put( 1, "Tokyo" );
capitalcities.put( 2, "Paris" );
capitalcities.put( 3, "Washington" );
capitalcities.put( 4, "Ankara" );
capitalcities.put( 5, "Brussels" );
auto capital_cities = hz_client.get_map("capitals").get();
capital_cities->put<int, std::string>(1, "Tokyo").get();
capital_cities->put<int, std::string>(2, "Paris").get();
capital_cities->put<int, std::string>(3, "Washington").get();
capital_cities->put<int, std::string>(4, "Ankara").get();
capital_cities->put<int, std::string>(5, "Brussels").get();
var capitalcities = hzClient.GetMap("capitals");
capitalcities.put( 1, "Tokyo" );
capitalcities.put( 2, "Paris" );
capitalcities.put( 3, "Washington" );
capitalcities.put( 4, "Ankara" );
capitalcities.put( 5, "Brussels" );
const capitalcities = await hzClient.getMap('capitals');
await capitalcities.put( 1, "Tokyo" );
await capitalcities.put( 2, "Paris" );
await capitalcities.put( 3, "Washington" );
await capitalcities.put( 4, "Ankara" );
await capitalcities.put( 5, "Brussels" );
capital_cities = hz_client.get_map("capitals").blocking()
capital_cities.put(1, "Tokyo")
capital_cities.put(2, "Paris")
capital_cities.put(3, "Washington")
capital_cities.put(4, "Ankara")
capital_cities.put(5, "Brussels")
capitalcities, _ := hzClient.GetMap("capitals")
capitalcities.Put( 1, "Tokyo" );
capitalcities.Put( 2, "Paris" );
capitalcities.Put( 3, "Washington" );
capitalcities.Put( 4, "Ankara" );
capitalcities.Put( 5, "Brussels" );
Adding Data to A Map
In the example code above, we not only created a map, but we added data to it using the map.put()
method. This method returns the old value of the map entry upon completion. For a new map, of course, this value will be null.
An alternative is to use the map.set()
method. This method adds the data to the map, but does not return the old value. If you do not need the value - for example, if you are performing a bulk load operation - you will improve the performance of the operation by using the map.set()
method.
Map<Integer, String> capitalcities = hzClient.getMap( "capitals" );
capitalcities.set( 1, "Tokyo" );
capitalcities.set( 2, "Paris" );
capitalcities.set( 3, "Washington" );
capitalcities.set( 4, "Ankara" );
capitalcities.set( 5, "Brussels" );
auto capital_cities = hz_client.get_map("capitals").get();
capital_cities->set<int, std::string>(1, "Tokyo").get();
capital_cities->set<int, std::string>(2, "Paris").get();
capital_cities->set<int, std::string>(3, "Washington").get();
capital_cities->set<int, std::string>(4, "Ankara").get();
capital_cities->set<int, std::string>(5, "Brussels").get();
await using var capitalCities = await client.GetMapAsync<int, string>("capitals");
await capitalCities.SetAsync(1, "Tokyo");
await capitalCities.SetAsync(2, "Paris");
await capitalCities.SetAsync(3, "Washington");
await capitalCities.SetAsync(4, "Ankara");
await capitalCities.SetAsync(5, "Brussels");
const capitalCities = await hzInstance.getMap('capitals');
await capitalCities.set( 1, "Tokyo" );
await capitalCities.set( 2, "Paris" );
await capitalCities.set( 3, "Washington" );
await capitalCities.set( 4, "Ankara" );
await capitalCities.set( 5, "Brussels" );
capital_cities = hz_client.get_map("capitals").blocking()
capital_cities.set(1, "Tokyo")
capital_cities.set(2, "Paris")
capital_cities.set(3, "Washington")
capital_cities.set(4, "Ankara")
capital_cities.set(5, "Brussels")
// error handling is omitted for brevity
capitalCities, _ := hzClient.GetMap("capitals")
capitalCities.Set(1, "Tokyo")
capitalCities.Set(2, "Paris")
capitalCities.Set(3, "Washington")
capitalCities.Set(4, "Ankara")
capitalCities.Set(5, "Brussels")
Writing Primitives to a Map
Hazelcast runs on Java, which uses defined primitive types. If you are writing data in a single field (as opposed to an object), and you do not specify the primitive type when creating your map, the Hazelcast cluster will assign the following types based on the format of the data in the value field:
Primitive Type | Data Description |
---|---|
|
Any whole number from -2147483648 to 2147483647 |
|
Any whole number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
|
Any character string |
|
Any floating point number (64-bit limit) |
If your preferred language does not have the concept of primitive types, you need to be aware of these assumptions, particularly if you have numeric data you want to handle as strings rather than integers. Make sure you use the appropriate indicator for your language (e.g. enclose strings in quotes) to distinguish strings from numeric data.
Hazelcast serializes - that is, converts to binary format - primitives using built-in serializers optimized for each primitive type. You can override these built-in serializers if desired. Refer to the Serialization section of the documentation for details.
Writing Objects to a Map
You can load objects into a map. When you define a map that holds objects, you need to invoke the serialization method that you want used to convert your objects into binary format. Hazelcast offers several different serialization methods, which are discussed in detail in the Serialization section of the documentation. For all programming languages, you can choose one of the following methods:
-
IdentifiedDataSerializable
: provides fast serialization, avoids reflection and long class names. See the IdentifiedDataSerializable section. -
Portable
: Provides partial deserialization for queries, improving query performance. Needs more memory to store metadata. See the Implementing Portable Serialization section. -
Compact
: Provides partial deserialization for queries, improving query performance. More memory efficient than Portable. See the Implementing Compact Serialization section. -
Custom Serialization (using StreamSerializer and ByteArraySerializer).
The documentation sections linked above include code samples for all client languages. There are additional serialization options for Java clients, which are also documented in the Serialization section.
Writing JSON to a Map
You can use JSON values both as keys and values in a map.
If you plan on querying your JSON data, it is best practice to write it to a map using the HazelcastJsonValue
object because it adds metadata to your map to make queries faster.
However, this metadata also adds some processing and memory overhead because Hazelcast must preprocess JSON values and store metadata in memory.
As a result, if you do not plan on querying JSON values, you can save on the processing and memory overhead by disabling the metadata policy or writing JSON to a map as a string.
String person1 = "{ \"name\": \"John\", \"age\": 35 }";
String person2 = "{ \"name\": \"Jane\", \"age\": 24 }";
String person3 = "{ \"name\": \"Trey\", \"age\": 17 }";
idPersonMap.put(1, new HazelcastJsonValue(person1));
idPersonMap.put(2, new HazelcastJsonValue(person2));
idPersonMap.put(3, new HazelcastJsonValue(person3));
std::string person1 = R"({ "name": "John", "age": 35 })";
std::string person2 = R"({ "name": "Jane", "age": 24 })";
std::string person3 = R"({ "name": "Trey", "age": 17 })";
id_person_map->put<int, hazelcast::client::hazelcast_json_value>(1, person1).get();
id_person_map->put<int, hazelcast::client::hazelcast_json_value>(2, person2).get();
id_person_map->put<int, hazelcast::client::hazelcast_json_value>(3, person3).get();
idPersonMap.put(1, new HazelcastJsonValue("{ \"name\": \"John\", \"age\": 35 }"));
idPersonMap.put(2, new HazelcastJsonValue("{ \"name\": \"Jane\", \"age\": 24 }"));
idPersonMap.put(3, new HazelcastJsonValue("{ \"name\": \"Trey\", \"age\": 17 }"));
const person1 = new HazelcastJsonValue(JSON.stringify({ name: "John", "age": 35 }));
const person2 = new HazelcastJsonValue(JSON.stringify({ name: "Jane", "age": 24 }));
const person3 = new HazelcastJsonValue(JSON.stringify({ name: "Trey", "age": 17 }));
await idPersonMap.put(0, new HazelcastJsonValue(JSON.stringify(person1)));
await idPersonMap.put(1, new HazelcastJsonValue(JSON.stringify(person2)));
await idPersonMap.put(2, new HazelcastJsonValue(JSON.stringify(person3)));
person1 = '{ \"name\": \"John\", \"age\": 35 }'
person2 = '{ \"name\": \"Jane\", \"age\": 24 }'
person3 = '{ \"name\": \"Trey\", \"age\": 17 }'
id_person_map.put(1, HazelcastJsonValue(person1))
id_person_map.put(2, HazelcastJsonValue(person2))
id_person_map.put(3, HazelcastJsonValue(person3))
person1, _ := core.CreateHazelcastJSONValue( { name: "John", "age": 35 } )
person2, _ := core.CreateHazelcastJSONValue( { name: "Jane", "age": 24 } )
person3, _ := core.CreateHazelcastJSONValue( { name: "Trey", "age": 17 } )
idPersonMap.Put( 1, person1 );
idPersonMap.Put( 2, person2 );
idPersonMap.Put( 3, person3 );
Hazelcast does not check the validity of JSON strings written to maps. You should make sure that your JSON strings are valid before writing them to a map. |
Disabling the Metadata Policy
To disable the metadata policy, set the metadata-policy
configuration element to OFF
.
Declarative Configuration:
<hazelcast>
...
<map name="map-a">
<!--
valid values for metadata-policy are:
- OFF
- CREATE_ON_UPDATE (default)
-->
<metadata-policy>OFF</metadata-policy>
</map>
...
</hazelcast>
hazelcast:
map:
map-a:
# valid values for metadata-policy are:
# - OFF
# - CREATE_ON_UPDATE (default)
metadata-policy: OFF
Programmatic Configuration:
MapConfig mapConfig = new MapConfig();
mapConfig.setMetadataPolicy(MetadataPolicy.OFF);
Other Methods to Add Data
If you are working with an external system of record such as a data store, Hazelcast provides a mechanism for automatically loading data from that system into an in-memory map, then keeping that external database synchronized with any changes to the in-memory store. See Building a Cache with MapStore.
A map can also be a sink for Hazelcast’s Jet processing engine. In this case, Jet creates the map and performs the map.put
operations for data as it is processed. Refer to the Jet engine documentation for details on using in-memory storage as a data sink.