Quick Start

This guide provides a brief, hands-on introduction to Bifurcan's core concepts. We'll explore creating collections and leveraging the library's unique approach to mutability.

Your First Immutable Map

Let's start by creating an immutable Map. In Bifurcan, update operations like put return a new map instance, leaving the original unchanged.

import io.lacuna.bifurcan.Map;

public class QuickStart {
    public static void main(String[] args) {
        // Create an empty immutable map
        IMap<String, Integer> m1 = new Map<>();

        // 'put' returns a new map with the added entry
        IMap<String, Integer> m2 = m1.put("hello", 1);

        // 'm1' remains unchanged
        System.out.println("m1 size: " + m1.size()); // prints 0

        // 'm2' has the new data
        System.out.println("m2 size: " + m2.size()); // prints 1
        System.out.println("m2 value for 'hello': " + m2.get("hello").get()); // prints 1
    }
}

Efficient Batch Updates with Linear Collections

Creating a new map for every addition can be inefficient in a tight loop. Bifurcan solves this with linear collections, which are temporarily mutable.

The linear() method returns a mutable version of the collection. You can perform batch updates on it efficiently. When you're done, forked() returns a new immutable version, ready to be shared safely.

import io.lacuna.bifurcan.IMap;
import io.lacuna.bifurcan.Map;

public class LinearExample {
    public static void main(String[] args) {
        // Start with a linear (mutable) map
        IMap<Long, String> linearMap = new Map<Long, String>().linear();

        // Perform 1000 in-place additions
        // This is much faster than creating 1000 intermediate immutable maps
        for (long i = 0; i < 1000; i++) {
            linearMap.put(i, "value_" + i);
        }

        // When done, fork it back into an immutable map
        IMap<Long, String> immutableMap = linearMap.forked();

        System.out.println("Final map size: " + immutableMap.size()); // prints 1000
        System.out.println("Is it linear? " + immutableMap.isLinear()); // prints false
    }
}
This pattern gives you the performance of mutable data structures for high-volume updates while preserving the safety and predictability of immutable structures for the rest of your application.

For cases where a collection will only be used in a mutable way, Bifurcan also provides permanently linear collections like LinearMap and LinearList.