List
Hazelcast List, also known as IList, is similar to Hazelcast Set - it is a distributed collection, but it allows duplicate elements and preserves the order of elements.
Hazelcast List is a non-partitioned data structure where values and each backup are represented by their own single partition.
Hazelcast List cannot be scaled beyond the capacity of a single machine. All items are copied to local and iteration occurs locally.
You can also use list as a source or sink for batch processing when building your data pipelines. You can fill a list with data, consume it in a Hazelcast job and send the results to another list. See the List Connector guide.
Creating a List
When you start a Hazelcast member with default configuration, it will have an empty list named default
.
See Start a Local Cluster in Docker for a quick cluster startup.
You can either use this default
list or create your own using the list’s getter methods as shown in the below
example. If you pass a name other than default
as the list name in these methods, it creates a new list with
the given name; otherwise, it will use this existing list.
In this example, we create a list called list
, add items to it, and print the items.
-
Add the following to your file:
import com.hazelcast.client.HazelcastClient; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.collection.ISet; import java.util.Collection; public class Client { public static void main(String[] args) throws Exception { HazelcastInstance client = HazelcastClient.newHazelcastClient(); IList<String> list = client.getList("list"); (1) (2) list.add("Tokyo"); list.add("Paris"); list.add("London"); list.add("New York"); System.out.println("Putting finished!"); } }
1 Create or access the List called list
.2 Add items to list
.
-
Add the following to your file:
#include <hazelcast/client/hazelcast_client.h> int main() { auto hz = hazelcast::new_client().get(); auto list = hz.get_list("list").get(); (1) (2) list->add("Tokyo").then(boost::launch::deferred, [=] (boost::future<bool> f) { if (f.get()) { std::cout << "First addition is successfull!!!" << '\n'; list->add("Paris").get(); list->add("London").get(); list->add("New York").get(); } }); std::cout << "Putting finished!" << std::endl; std::cout << "Finished" << std::endl; return 0; }
1 Create or access the List called list
.2 Add items to list
.
-
Add the following to your file:
using System; using System.Threading.Tasks; namespace Hazelcast.Examples.DistributedObjects { public class ListExample { public static async Task Main(string[] args) { var options = new HazelcastOptionsBuilder() .With(args) .WithConsoleLogger() .Build(); await using var client = await HazelcastClientFactory.StartNewClientAsync(options); await using var list = await client.GetListAsync<string>("list"); (1) (2) await list.AddAsync("Tokyo"); await list.AddAsync("Paris"); await list.AddAsync("London"); await list.AddAsync("New York"); Console.WriteLine("Get: " + await list.GetAsync(0)); Console.WriteLine("All: " + string.Join(", ", await list.GetAllAsync())); Console.WriteLine("Contains: " + await list.ContainsAsync("item2")); Console.WriteLine("Count: " + await list.GetSizeAsync()); Console.WriteLine("Sublist: " + string.Join(", ", await list.GetSublistAsync(0, 2))); // destroy the list await client.DestroyAsync(list); } } }
1 Create or access the List called list
.2 Add items to list
.
-
Install the Node.js client library.
npm install hazelcast-client
-
Add the following to your file:
'use strict'; const { Client } = require('hazelcast-client'); (async () => { try { const client = await Client.newHazelcastClient(); const list = await client.getList('list'); (1) (2) await list.add('Tokyo'); console.log('Added Tokyo'); await list.add('Paris', 1); console.log('Added Paris to index 1'); await list.add('London'); console.log('Added London'); (3) await list.remove('Paris'); console.log('Removed Paris'); const removedItem = await list.removeAt(1); console.log('Removed', removedItem); await client.shutdown(); } catch (err) { console.error('Error occurred:', err); process.exit(1); } })();
1 Create or access the List called list
.2 Add items to list
.3 Remove items from list
.
-
Install the Python client library.
pip install hazelcast-python-client
-
Add the following to your file:
import hazelcast client = hazelcast.HazelcastClient() my_list = client.get_list("list") (1) (2) my_list.add("Tokyo") my_list.add("Paris") my_list.add("London") my_list.add("New York") my_list.add("Istanbul") print("List size: {}".format(my_list.size().result())) print("First element: {}".format(my_list.get(0).result())) print("Contains London: {}".format(my_list.contains("London").result())) print("Sublist: {}".format(my_list.sub_list(3, 4).result())) (3) my_list.remove("Tokyo") print("Final size: {}".format(my_list.size().result())) client.shutdown()
1 Create or access the List called list
.2 Add items to list
.3 Remove items from list
.
-
Install the Go client library.
go get github.com/hazelcast/hazelcast-go-client
-
Add the following to your file:
package main import ( "context" "fmt" "log" "math/rand" "time" "github.com/hazelcast/hazelcast-go-client" ) func main() { ctx := context.TODO() client, err := hazelcast.StartNewClient(ctx) if err != nil { log.Fatal(err) } rand.Seed(time.Now().Unix()) listName := fmt.Sprintf("sample-%d", rand.Int()) list, err := client.GetList(ctx, listName) (1) if err != nil { log.Fatal(err) } size, err := list.Size(ctx) if err != nil { log.Fatal(err) } fmt.Println(size) (2) list.Add(ctx, "Tokyo") list.Add(ctx, "Paris") list.Add(ctx, "London") list.Add(ctx, "New York") size, err = list.Size(ctx) if err != nil { log.Fatal(err) } fmt.Println(size) // Shutdown client client.Shutdown(ctx) }
1 Create or access the List called list
.2 Add items to list
.
Hazelcast List uses item listeners to listen to events that occur when items are added to and removed from the list. See the Listening for Item Events section for information about how to create an item listener class and register it.
Configuring List
The following is an example list configuration.
<hazelcast>
...
<list name="default">
<statistics-enabled>false</statistics-enabled>
<backup-count>1</backup-count>
<async-backup-count>0</async-backup-count>
<max-size>10</max-size>
<item-listeners>
<item-listener>
com.hazelcast.examples.ItemListener
</item-listener>
</item-listeners>
<split-brain-protection-ref>splitbrainprotection-name</split-brain-protection-ref>
</list>
...
</hazelcast>
hazelcast:
list:
default:
statistics-enabled: false
backup-count: 1
async-backup-count: 0
max-size: 10
item-listeners:
- class-name: com.hazelcast.examples.ItemListener
split-brain-protection-ref: splitbrainprotection-name
Config config = new Config();
CollectionConfig collectionList = config.getListConfig("MyList");
collectionList.setBackupCount(1)
.setMaxSize(10)
.setSplitBrainProtectionName("splitbrainprotectionname");
The following are the configuration elements and their descriptions:
-
backup-count
: Count of synchronous backups. List is a non-partitioned data structure, so all entries of a list reside in one partition. For example, if this parameter is1
, there is one backup of the list in one other member. If it is2
, two members will have the backup. -
async-backup-count
: Count of asynchronous backups. See Backup Types to learn more about synchronous and asynchronous backups. -
statistics-enabled
: Specifies whether the statistics gathering is enabled for your list. If set tofalse
, you cannot collect statistics in your implementation. Its default value istrue
. -
max-size
: The maximum number of entries for this list. -
item-listeners
: Lets you add listeners (listener classes) for the list items. You can also set the attributeinclude-value
totrue
if you want the item event to contain the item values. You can set the attributelocal
totrue
if you want to listen the items on the local member. -
split-brain-protection-ref
: Name of the split-brain protection configuration that you want this list to use. See the Split-Brain Protection for IList and TransactionalList section.
Split-Brain Protection for IList and TransactionalList
IList & TransactionalList can be configured to check for a minimum number of available members before applying queue operations (see the Split-Brain Protection section). This is a check to avoid performing successful queue operations on all parts of a cluster during a network partition.
The following is a list of methods, grouped by the protection types, that support split-brain protection checks:
IList:
-
WRITE, READ_WRITE:
-
add
-
addAll
-
clear
-
remove
-
removeAll
-
set
-
-
READ, READ_WRITE:
-
add
-
contains
-
containsAll
-
get
-
indexOf
-
isEmpty
-
iterator
-
lastIndexOf
-
listIterator
-
size
-
subList
-
toArray
-
TransactionalList:
-
WRITE, READ_WRITE:
-
add
-
remove
-
-
READ, READ_WRITE:
-
size
-
The configuration is done on the member side and the following is an example.
<hazelcast>
...
<list name="default">
<split-brain-protection-ref>splitBrainProtectionRuleWithFourMembers</split-brain-protection-ref>
</list>
...
</hazelcast>
hazelcast:
list:
default:
split-brain-protection-ref: splitBrainProtectionRuleWithFourMembers
SplitBrainProtectionConfig splitBrainProtectionConfig = new SplitBrainProtectionConfig();
splitBrainProtectionConfig.setName("splitBrainProtectionRuleWithFourMembers")
.setEnabled(true)
.setMinimumClusterSize(4);
ListConfig listConfig = new ListConfig();
listConfig.setSplitBrainProtectionName("splitBrainProtectionRuleWithFourMembers");
Config config = new Config();
config.addSplitBrainProtectionConfig(splitBrainProtectionConfig);
config.addListConfig(listConfig);
The value of split-brain-protection-ref
should be the split-brain protection configuration name which you
configured under the split-brain-protection
element as explained in the Split-Brain Protection section.