This is a prerelease version.

View latest

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.

  • Java

  • C++

  • C Sharp

  • Node.js

  • Python

  • Go

  1. Install the Java client library

  2. 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.
  1. Install the latest C++ client library

  2. 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.
  1. Install the latest C Sharp client library

  2. 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.
  1. Install the Node.js client library.

    npm install hazelcast-client
  2. 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.
  1. Install the Python client library.

    pip install hazelcast-python-client
  2. 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.
  1. Install the Go client library.

    go get github.com/hazelcast/hazelcast-go-client
  2. 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.

  • XML

  • YAML

  • Java

<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 is 1, there is one backup of the list in one other member. If it is 2, 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 to false, you cannot collect statistics in your implementation. Its default value is true.

  • 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 attribute include-value to true if you want the item event to contain the item values. You can set the attribute local to true 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.

  • XML

  • YAML

  • Java

<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.