What’s the difference between a list and a dictionary in AL?

In a recent video, I confused the viewers by naming a Dictionary variable “List”. In this video, we go deep into the difference between lists and dictionaries. Check out the video:

https://youtu.be/BToaoPB9bug

In this video, Erik explains the fundamental differences between two important data structures in AL: List and Dictionary. He covers how each works under the hood, when to use one versus the other, and wraps up with a bonus insight about how JSON objects and arrays relate to these structures.

The List: A Modern Linked List

In computer science, one of the most foundational data structures is the linked list. In the classic sense, a linked list is a chain of data nodes where each node contains a pointer to the next (and sometimes the previous) node in the sequence.

For example, imagine four data entries:

  • Data1 contains a pointer to where Data2 lives in memory
  • Data2 points to Data3
  • Data3 points to Data4

In a doubly-linked list, each node also has a pointer back to its predecessor, so you can traverse in both directions. Adding a new entry (say Data5) is straightforward: allocate memory, update the last node’s pointer. Deleting a node (say Data3) simply means updating Data2‘s pointer to point to Data4 instead, then freeing Data3’s memory.

The List type in AL is essentially an evolved version of this concept. It’s a generic, indexed collection. You declare it with a single type parameter — the type of data it holds:

var
    List: List of [Text];
begin
    List.Add('Data1');
    List.Add('Data2');
    List.Add('Data3');
    List.Add('Data4');
    List.Add('Data5');

Each call to Add appends to the end of the list. Behind the scenes, the list maintains an index, so you can retrieve items by position:

Message(List.Get(3)); // Returns 'Data3'

However, if you don’t know the index of the item you’re looking for, your only option is to traverse the list and search — there’s no built-in key-based lookup.

Using a List as a Queue

One practical use case Erik demonstrates is using a list as a FIFO (First In, First Out) queue. The idea is simple: always add to the end, always consume from the front.

// Get the first item
Message(List.Get(1));

// Remove the first item
List.RemoveAt(1);

// Add a new item to the end
List.Add('Data6');

// Now the first item is what was previously second
Message(List.Get(1));

Running this code, the first message returns 'Data1'. After removing it and adding 'Data6', the second message returns 'Data2'. It’s a simple and effective in-memory queue. You could similarly implement a stack by always adding and removing from the same end.

A note on performance: the list has a Remove method that removes by value, but Erik cautions that this isn’t necessarily performant because it has to traverse the list to find the matching entry. Using RemoveAt with a known index is preferable when possible.

The Dictionary: A Hash Table Under the Hood

A dictionary is a fundamentally different data structure. It requires two type parameters: one for the key and one for the value (the payload).

var
    Dict: Dictionary of [Code[20], Text];
begin
    Dict.Add('C0454', 'Data1');
    Dict.Add('10000', 'Data2');
    Dict.Add('ABC343', 'Data3');
    Dict.Add('JJJFR', 'Data4');
    Dict.Add('YOUTUBE', 'Data5');

    Message(Dict.Get('YOUTUBE')); // Returns 'Data5'

Behind the scenes, the dictionary builds a hash table. When you add a key-value pair, the key is run through a hash function — similar in concept to cryptographic hashes like SHA-256, but optimized for speed rather than security. The hash function is designed to minimize collisions (cases where two different keys produce the same hash value).

The hash table maps each hash to its corresponding data. But what happens when two keys produce the same hash? The dictionary handles this with what is essentially a small list at each hash bucket. When a collision occurs, both key-value pairs are stored in that list, and a linear search within the bucket resolves which key maps to which value.

Why Dictionaries Are Fast

The key advantage of a dictionary is constant-time lookup. It doesn’t matter whether you have five entries or a million — looking up a key is essentially the same speed. This makes dictionaries the only choice when you need to do lookups at scale.

Erik mentions a practical example from a previous video where he used a dictionary to track whether a customer had already been seen:

// In that case, a Dictionary of [Code[20], Boolean] was used
// The Boolean payload was essentially irrelevant — 
// all that mattered was whether the key existed or not

Dictionary Limitations

The trade-off is that there is no sorting in a dictionary. The internal ordering is determined by hash values, which have no meaningful sort order. You can retrieve lists of keys and values:

Dict.Keys()   // Returns a list of all keys
Dict.Values() // Returns a list of all values

The only guarantee is that the list of keys and the list of values are in the same order relative to each other — but that order is not sorted or predictable.

A Note on Hash Tables

In C#, you can declare a HashTable directly, which is essentially a dictionary without a data payload. In AL, Microsoft’s guidance is to just use a dictionary. If you don’t need the payload, you can use a small type like Boolean as the value type. However, Erik notes that at large scale, even storing a million boolean values has a memory cost — with alignment overhead, you could be looking at roughly 4 megabytes of RAM. Whether that matters depends on your scenario.

Bonus: JSON Objects and Arrays Are the Same Concepts

Erik wraps up with an interesting bonus observation. A JsonObject in AL is essentially a dictionary with some extra features — the key is always text, but the value can be different data types:

var
    Dict: JsonObject;
begin
    Dict.Add('YOUTUBE', 'Data5');
    // Note: retrieval uses SelectToken or ReadAs methods

Similarly, a JsonArray is essentially a list:

var
    List: JsonArray;

If you look at the available methods on JsonArray, they’re very close to what you find on the List type. That’s because behind the scenes, a JSON array is implemented with something that looks like a list, and a JSON object is implemented with something that looks like a dictionary. In some cases, using a JsonObject instead of a Dictionary can be advantageous because you have more flexibility in the types of data you store in different parts of the structure.

The Full Source Code

Here’s the complete example Erik walked through, with the list code commented out so you can toggle between examples:

namespace DefaultPublisher.ListvsDictionary;

using Microsoft.Sales.Customer;

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage();
    var
        //List: List of [Text];
        Dict: Dictionary of [Code[20], Text];
    begin
        Dict.Add('C0454', 'Data1');
        Dict.Add('10000', 'Data2');
        Dict.Add('ABC343', 'Data3');
        Dict.Add('JJJFR', 'Data4');
        Dict.Add('YOUTUBE', 'Data5');

        message(Dict.Get('YOUTUBE'));

        // List.Add('Data1');
        // List.Add('Data2');
        // List.Add('Data3');
        // List.Add('Data4');
        // List.Add('Data5');

        // Message(List.Get(1));
        // List.RemoveAt(1);
        // List.Add('Data6');
        // Message(List.Get(1));
    end;
}

Summary

Here’s a quick comparison of the two data structures:

  • List: An ordered, indexed collection of a single data type. Great for sequential access, queues, stacks, and scenarios where order matters. Lookups require traversal.
  • Dictionary: A key-value store backed by a hash table. Provides near-instant key lookups regardless of size, but has no meaningful sort order. Ideal for lookups, deduplication, and associating values with unique keys.

Erik notes that he personally uses dictionaries far more often than lists, especially when collecting data for later lookup. But when you need ordered data or queue/stack behavior, the list is the right tool. And if you need flexible typing in your key-value store, consider that a JsonObject is essentially a dictionary with more flexibility — and a JsonArray is essentially a list. These data structures are among the most important additions to the AL language in modern times.