Collections: Lists (List
, LinearList
)
Bifurcan provides two primary list implementations that share a common IList
interface: the immutable List
and the mutable LinearList
.
List
(Immutable)
The immutable List
is an implementation of a Relaxed Radix Balanced Tree (RRB-Tree). This advanced structure gives it powerful performance characteristics:
- Efficient modifications at both ends:
addFirst
,addLast
,removeFirst
, andremoveLast
are highly optimized. - Fast random access and updates:
nth(idx)
andset(idx, val)
are efficient. - Near constant-time slicing and concatenation: Operations like
slice()
andconcat()
are exceptionally fast, makingList
ideal for workflows that involve splitting and joining lists.
import io.lacuna.bifurcan.List;
// Create a list
List<String> list1 = List.of("a", "b", "c");
// Add an element
List<String> list2 = list1.addLast("d"); // list1 is unchanged
// Concatenate
List<String> list3 = list2.concat(List.of("e", "f")); // [a, b, c, d, e, f]
// Slice
List<String> slice = list3.slice(1, 4); // [b, c, d]
LinearList
(Mutable)
LinearList
is a mutable list that combines the benefits of java.util.ArrayList
and java.util.ArrayDeque
. It is backed by a circular buffer, providing:
- Constant-time additions and removals from both the front and back.
- Constant-time random-access reads and writes.
It is ideal for scenarios where you need to build up a list inside a single thread of execution before potentially converting it to an immutable List
using forked()
.
import io.lacuna.bifurcan.LinearList;
// Create a mutable list
LinearList<Integer> list = new LinearList<>();
// Efficiently build the list
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
list.addLast(i);
} else {
list.addFirst(i);
}
}