CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-vavr--vavr

Object-functional language extension to Java 8+ providing persistent collections, functional abstractions, and monadic control types.

Pending
Overview
Eval results
Files

collections.mddocs/

Collections

Comprehensive immutable collection library with persistent data structures including sequential collections, sets, maps, and specialized collections optimized for functional programming.

Capabilities

Base Collection Interfaces

Core interfaces that define the collection hierarchy and common operations.

/**
 * Root interface for all traversable collections
 */
interface Traversable<T> extends Value<T> {
    // Factory methods
    static <T> Traversable<T> empty();
    static <T> Traversable<T> of(T... elements);
    
    // Basic operations
    int size();
    boolean isEmpty();
    boolean contains(T element);
    
    // Transformation operations
    <U> Traversable<U> map(Function<? super T, ? extends U> mapper);
    Traversable<T> filter(Predicate<? super T> predicate);
    <U> U foldLeft(U zero, BiFunction<? super U, ? super T, ? extends U> combine);
    <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> combine);
    
    // Terminal operations
    String mkString();
    String mkString(String delimiter);
    String mkString(String prefix, String delimiter, String suffix);
}

/**
 * Base interface for sequential collections
 */
interface Seq<T> extends Traversable<T> {
    // Access operations
    T get(int index);
    int indexOf(T element);
    int lastIndexOf(T element);
    
    // Transformation operations
    Seq<T> append(T element);
    Seq<T> prepend(T element);
    Seq<T> insert(int index, T element);
    Seq<T> remove(T element);
    Seq<T> removeAt(int index);
    
    // Subsequence operations
    Seq<T> slice(int beginIndex, int endIndex);
    Seq<T> take(int n);
    Seq<T> drop(int n);
    Seq<T> reverse();
    
    // Grouping operations
    <K> Map<K, ? extends Seq<T>> groupBy(Function<? super T, ? extends K> classifier);
}

/**
 * Interface for indexed sequential collections with O(1) random access
 */
interface IndexedSeq<T> extends Seq<T> {
    // Override for performance
    T get(int index); // O(1) access
}

/**
 * Interface for linear sequential collections with O(1) head/tail access
 */
interface LinearSeq<T> extends Seq<T> {
    T head();
    LinearSeq<T> tail();
    boolean isEmpty();
}

List - Immutable Linked List

Immutable singly-linked list implementation optimized for prepend operations and sequential access.

/**
 * Immutable singly-linked list (LIFO stack)
 */
interface List<T> extends LinearSeq<T> {
    // Factory methods
    static <T> List<T> empty();
    static <T> List<T> of();
    static <T> List<T> of(T element);
    static <T> List<T> of(T... elements);
    static <T> List<T> ofAll(Iterable<? extends T> elements);
    static <T> List<T> fill(int n, T element);
    static <T> List<T> fill(int n, Supplier<? extends T> supplier);
    static List<Integer> range(int from, int toExclusive);
    static List<Integer> rangeClosed(int from, int toInclusive);
    
    // Stack operations (O(1))
    T head();                                    // Get first element
    List<T> tail();                             // Get all but first element
    List<T> prepend(T element);                 // Add to front
    static <T> List<T> cons(T head, List<T> tail); // Construct from head and tail
    
    // List operations
    List<T> append(T element);                  // Add to end (O(n))
    List<T> appendAll(Iterable<? extends T> elements);
    List<T> prependAll(Iterable<? extends T> elements);
    
    // Transformation operations (return new List)
    <U> List<U> map(Function<? super T, ? extends U> mapper);
    List<T> filter(Predicate<? super T> predicate);
    <U> List<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper);
    List<T> distinct();
    List<T> sorted();
    List<T> sorted(Comparator<? super T> comparator);
    
    // Combining operations
    List<T> removeFirst(Predicate<? super T> predicate);
    List<T> removeLast(Predicate<? super T> predicate);
    List<T> removeAll(T element);
    List<T> replace(T currentElement, T newElement);
    List<T> replaceAll(T currentElement, T newElement);
    
    // Zipping operations
    <U> List<Tuple2<T, U>> zip(Iterable<? extends U> that);
    <U, R> List<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper);
    List<Tuple2<T, Integer>> zipWithIndex();
}

Usage Examples:

import io.vavr.collection.List;

// Creating lists
List<Integer> empty = List.empty();
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<String> names = List.of("Alice", "Bob", "Charlie");

// Stack operations (efficient)
List<Integer> withZero = numbers.prepend(0);  // [0, 1, 2, 3, 4, 5]
Integer first = numbers.head();               // 1
List<Integer> rest = numbers.tail();          // [2, 3, 4, 5]

// Functional operations
List<Integer> doubled = numbers.map(x -> x * 2);
List<Integer> evens = numbers.filter(x -> x % 2 == 0);
List<String> words = List.of("hello", "world").map(String::toUpperCase);

// Combining lists
List<Integer> extended = numbers.append(6).appendAll(List.of(7, 8, 9));
List<Integer> combined = List.of(0).appendAll(numbers);

// Pattern matching on lists
String describe(List<Integer> list) {
    return list.isEmpty() ? "empty" : 
           list.tail().isEmpty() ? "single: " + list.head() :
           "multiple starting with " + list.head();
}

Vector - Immutable Indexed Sequence

High-performance immutable indexed sequence with efficient random access and updates.

/**
 * Immutable indexed sequence with O(log n) access and updates
 */
class Vector<T> implements IndexedSeq<T> {
    // Factory methods
    static <T> Vector<T> empty();
    static <T> Vector<T> of(T... elements);
    static <T> Vector<T> ofAll(Iterable<? extends T> elements);
    static <T> Vector<T> fill(int n, T element);
    static Vector<Integer> range(int from, int toExclusive);
    
    // Indexed access (O(log n))
    T get(int index);
    Vector<T> update(int index, T element);
    
    // Modification operations (O(log n))
    Vector<T> append(T element);
    Vector<T> prepend(T element);
    Vector<T> insert(int index, T element);
    Vector<T> removeAt(int index);
    
    // Transformation operations
    <U> Vector<U> map(Function<? super T, ? extends U> mapper);
    Vector<T> filter(Predicate<? super T> predicate);
    Vector<T> sorted();
    Vector<T> sorted(Comparator<? super T> comparator);
    
    // Subsequence operations
    Vector<T> slice(int beginIndex, int endIndex);
    Vector<T> take(int n);
    Vector<T> drop(int n);
    Vector<T> reverse();
}

Array - Immutable Array Wrapper

Immutable wrapper around Java arrays providing indexed access with functional programming operations.

/**
 * Immutable wrapper for Object[] with O(1) indexed access
 */
class Array<T> implements IndexedSeq<T> {
    // Factory methods
    static <T> Array<T> empty();
    static <T> Array<T> of(T... elements);
    static <T> Array<T> ofAll(Iterable<? extends T> elements);
    static <T> Array<T> ofAll(java.util.stream.Stream<? extends T> javaStream);
    static <T> Array<T> fill(int n, T element);
    static <T> Array<T> fill(int n, Supplier<? extends T> supplier);
    static Array<Integer> range(int from, int toExclusive);
    static Array<Integer> rangeClosed(int from, int toInclusive);
    
    // Indexed access (O(1))
    T get(int index);                           // Direct array access
    Array<T> update(int index, T element);      // Create new array with updated element
    
    // Modification operations (create new array)
    Array<T> append(T element);
    Array<T> appendAll(Iterable<? extends T> elements);
    Array<T> prepend(T element);
    Array<T> prependAll(Iterable<? extends T> elements);
    Array<T> insert(int index, T element);
    Array<T> insertAll(int index, Iterable<? extends T> elements);
    Array<T> remove(T element);
    Array<T> removeAt(int index);
    Array<T> removeAll(Iterable<? extends T> elements);
    
    // Transformation operations
    <U> Array<U> map(Function<? super T, ? extends U> mapper);
    Array<T> filter(Predicate<? super T> predicate);
    <U> Array<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper);
    Array<T> distinct();
    Array<T> distinctBy(Comparator<? super T> comparator);
    Array<T> sorted();
    Array<T> sorted(Comparator<? super T> comparator);
    
    // Subsequence operations
    Array<T> slice(int beginIndex, int endIndex);
    Array<T> take(int n);
    Array<T> drop(int n);
    Array<T> takeWhile(Predicate<? super T> predicate);
    Array<T> dropWhile(Predicate<? super T> predicate);
    Array<T> reverse();
    
    // Conversion operations
    Object[] toJavaArray();                     // Direct array access
    T[] toJavaArray(Class<T> componentType);    // Typed array conversion
    java.util.List<T> toJavaList();
    
    // Zipping operations
    <U> Array<Tuple2<T, U>> zip(Iterable<? extends U> that);
    <U, R> Array<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper);
    Array<Tuple2<T, Integer>> zipWithIndex();
}

Usage Examples:

import io.vavr.collection.Array;

// Creating arrays
Array<Integer> empty = Array.empty();
Array<Integer> numbers = Array.of(1, 2, 3, 4, 5);
Array<String> words = Array.of("hello", "world", "vavr");

// O(1) indexed access (advantage over List)
Integer third = numbers.get(2);                // 3 (no traversal needed)
Array<Integer> updated = numbers.update(1, 10); // [1, 10, 3, 4, 5]

// Functional operations
Array<Integer> doubled = numbers.map(x -> x * 2);
Array<Integer> evens = numbers.filter(x -> x % 2 == 0);
Array<String> lengths = words.map(w -> "Length: " + w.length());

// Array-specific operations
Array<Integer> range = Array.range(1, 6);      // [1, 2, 3, 4, 5]
Array<String> filled = Array.fill(3, "test");  // ["test", "test", "test"]

// Efficient bulk operations
Array<Integer> extended = numbers.appendAll(Array.of(6, 7, 8));
Array<Integer> combined = Array.of(0).prependAll(numbers);

// Direct conversion to Java arrays (efficient)
Integer[] javaArray = numbers.toJavaArray(Integer.class);
Object[] objectArray = numbers.toJavaArray();

// Sorting (creates new array)
Array<String> sorted = words.sorted();
Array<Integer> descending = numbers.sorted((a, b) -> b.compareTo(a));

// Memory-efficient operations
Array<Integer> slice = numbers.slice(1, 4);    // [2, 3, 4]
Array<Integer> first3 = numbers.take(3);       // [1, 2, 3]
Array<Integer> skip2 = numbers.drop(2);        // [3, 4, 5]

// Pattern matching style operations
String describe = numbers.isEmpty() ? "empty" :
                 numbers.size() == 1 ? "single" : 
                 "array of " + numbers.size() + " elements";

Array is particularly useful when you need:

  • O(1) indexed access (unlike List which is O(n))
  • Efficient conversion to/from Java arrays
  • Memory efficiency for large datasets
  • Bulk operations on array-like data structures

HashMap - Immutable Hash Map

Hash-based immutable map implementation with efficient key-value operations.

/**
 * Immutable hash-based map with O(1) expected time operations
 */
class HashMap<K, V> implements Map<K, V> {
    // Factory methods
    static <K, V> HashMap<K, V> empty();
    static <K, V> HashMap<K, V> of(K key, V value);
    static <K, V> HashMap<K, V> of(K k1, V v1, K k2, V v2);
    // ... up to 10 key-value pairs
    static <K, V> HashMap<K, V> ofEntries(Tuple2<? extends K, ? extends V>... entries);
    static <K, V> HashMap<K, V> ofEntries(Iterable<? extends Tuple2<? extends K, ? extends V>> entries);
    
    // Map operations
    Option<V> get(K key);                       // Get value for key
    V getOrElse(K key, V defaultValue);        // Get value or default
    boolean containsKey(K key);                 // Check if key exists
    boolean containsValue(V value);             // Check if value exists
    
    // Modification operations (return new HashMap)
    HashMap<K, V> put(K key, V value);         // Add/update key-value pair
    HashMap<K, V> put(Tuple2<? extends K, ? extends V> entry);
    HashMap<K, V> putAll(Iterable<? extends Tuple2<? extends K, ? extends V>> entries);
    HashMap<K, V> remove(K key);               // Remove key-value pair
    HashMap<K, V> removeAll(Iterable<? extends K> keys);
    
    // Transformation operations
    <K2, V2> HashMap<K2, V2> map(BiFunction<? super K, ? super V, Tuple2<K2, V2>> mapper);
    <V2> HashMap<K, V2> mapValues(Function<? super V, ? extends V2> mapper);
    HashMap<K, V> filter(BiPredicate<? super K, ? super V> predicate);
    HashMap<K, V> filterKeys(Predicate<? super K> predicate);
    HashMap<K, V> filterValues(Predicate<? super V> predicate);
    
    // Collection views
    Set<K> keySet();                           // Get all keys
    Traversable<V> values();                   // Get all values
    Set<Tuple2<K, V>> entrySet();             // Get all key-value pairs
    
    // Merging operations
    HashMap<K, V> merge(Map<? extends K, ? extends V> that);
    <U, R> HashMap<K, R> merge(Map<? extends K, ? extends U> that, 
                               BiFunction<? super V, ? super U, ? extends R> collisionResolution);
}

Usage Examples:

import io.vavr.collection.HashMap;
import io.vavr.collection.Map;
import io.vavr.Tuple;

// Creating maps
Map<String, Integer> scores = HashMap.of(
    "Alice", 95,
    "Bob", 87,
    "Charlie", 92
);

// Map operations
Integer aliceScore = scores.get("Alice").getOrElse(0);
boolean hasAlice = scores.containsKey("Alice");

// Adding/updating entries
Map<String, Integer> updated = scores.put("David", 89);
Map<String, Integer> incremented = scores.mapValues(score -> score + 5);

// Filtering
Map<String, Integer> highScores = scores.filter((name, score) -> score > 90);
Map<String, Integer> aNames = scores.filterKeys(name -> name.startsWith("A"));

// Working with entries
scores.forEach((name, score) -> 
    System.out.println(name + ": " + score));

// Converting between representations
java.util.Map<String, Integer> javaMap = scores.toJavaMap();

HashSet - Immutable Hash Set

Hash-based immutable set implementation with efficient membership testing and set operations.

/**
 * Immutable hash-based set with O(1) expected time operations
 */
class HashSet<T> implements Set<T> {
    // Factory methods
    static <T> HashSet<T> empty();
    static <T> HashSet<T> of(T element);
    static <T> HashSet<T> of(T... elements);
    static <T> HashSet<T> ofAll(Iterable<? extends T> elements);
    
    // Set operations
    boolean contains(T element);                // Test membership
    HashSet<T> add(T element);                 // Add element
    HashSet<T> addAll(Iterable<? extends T> elements);
    HashSet<T> remove(T element);              // Remove element
    HashSet<T> removeAll(Iterable<? extends T> elements);
    
    // Set algebra operations
    HashSet<T> union(Set<? extends T> that);          // Union (A ∪ B)
    HashSet<T> intersect(Set<? extends T> that);      // Intersection (A ∩ B)  
    HashSet<T> diff(Set<? extends T> that);           // Difference (A - B)
    
    // Transformation operations
    <U> HashSet<U> map(Function<? super T, ? extends U> mapper);
    HashSet<T> filter(Predicate<? super T> predicate);
    <U> HashSet<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper);
    
    // Subset operations
    boolean isSubsetOf(Set<? extends T> that);
    boolean isProperSubsetOf(Set<? extends T> that);
}

Stream - Lazy Infinite Sequence

Lazy evaluation sequence that can represent infinite collections with on-demand computation.

/**
 * Lazy infinite sequence with on-demand evaluation
 */
class Stream<T> implements LinearSeq<T> {
    // Factory methods  
    static <T> Stream<T> empty();
    static <T> Stream<T> of(T... elements);
    static <T> Stream<T> ofAll(Iterable<? extends T> elements);
    static <T> Stream<T> continually(T element);              // Infinite constant stream
    static <T> Stream<T> continually(Supplier<? extends T> supplier); // Infinite generated stream
    static <T> Stream<T> iterate(T seed, Function<? super T, ? extends T> f); // Infinite iteration
    static Stream<Integer> from(int start);                   // Infinite arithmetic progression
    static Stream<Integer> range(int from, int toExclusive);  // Finite range
    
    // Stream operations (lazy)
    T head();                                  // First element (evaluated)
    Stream<T> tail();                         // Rest of stream (lazy)
    boolean isEmpty();                         // Check if stream is empty
    
    // Transformation operations (lazy)
    <U> Stream<U> map(Function<? super T, ? extends U> mapper);
    Stream<T> filter(Predicate<? super T> predicate);
    <U> Stream<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper);
    Stream<T> distinct();
    
    // Limiting operations (finite results)
    Stream<T> take(int n);                    // Take first n elements
    Stream<T> takeWhile(Predicate<? super T> predicate); // Take while condition holds
    Stream<T> drop(int n);                    // Skip first n elements  
    Stream<T> dropWhile(Predicate<? super T> predicate); // Skip while condition holds
    
    // Terminal operations (force evaluation)
    List<T> toList();                         // Convert to List (forces evaluation)
    Vector<T> toVector();                     // Convert to Vector
    T reduce(BinaryOperator<T> op);          // Reduce to single value
    <U> U foldLeft(U zero, BiFunction<? super U, ? super T, ? extends U> combine);
    
    // Zipping operations
    <U> Stream<Tuple2<T, U>> zip(Iterable<? extends U> that);
    Stream<Tuple2<T, Integer>> zipWithIndex();
}

Usage Examples:

import io.vavr.collection.Stream;
import io.vavr.collection.List;

// Infinite streams
Stream<Integer> naturals = Stream.from(1);           // 1, 2, 3, 4, ...
Stream<Integer> evens = naturals.filter(x -> x % 2 == 0); // 2, 4, 6, 8, ...
Stream<Integer> powers = Stream.iterate(1, x -> x * 2);   // 1, 2, 4, 8, 16, ...

// Taking finite portions
List<Integer> first10Evens = evens.take(10).toList();
List<Integer> powersUpTo1000 = powers.takeWhile(x -> x <= 1000).toList();

// Lazy evaluation demonstration
Stream<String> expensive = Stream.continually(() -> {
    System.out.println("Computing...");
    return "expensive";
});

// Nothing printed yet - computation is lazy
Stream<String> transformed = expensive.map(String::toUpperCase);

// Still nothing printed - still lazy
String first = transformed.head(); // Now prints "Computing..." once

// Fibonacci sequence example
Stream<Integer> fibonacci = Stream.of(1, 1)
    .appendSelf(self -> self.zip(self.tail()).map(t -> t._1() + t._2()));
List<Integer> first10Fib = fibonacci.take(10).toList(); // [1,1,2,3,5,8,13,21,34,55]

Specialized Collections

Additional collection types for specific use cases.

/**
 * Character sequence with string-like operations
 */
class CharSeq implements IndexedSeq<Character> {
    static CharSeq empty();
    static CharSeq of(String string);
    static CharSeq of(char... chars);
    
    // String-like operations
    char charAt(int index);
    CharSeq substring(int beginIndex);
    CharSeq substring(int beginIndex, int endIndex);
    List<CharSeq> split(String delimiter);
    CharSeq replace(char oldChar, char newChar);
    CharSeq toLowerCase();
    CharSeq toUpperCase();
    CharSeq trim();
    
    // Conversion
    String mkString();
    char[] toCharArray();
}

/**
 * FIFO queue interface
 */
interface Queue<T> extends Traversable<T> {
    static <T> Queue<T> empty();
    static <T> Queue<T> of(T... elements);
    
    T peek();                           // Get front element without removing
    Option<T> peekOption();            // Safe peek operation
    Queue<T> enqueue(T element);       // Add to rear
    Tuple2<T, Queue<T>> dequeue();     // Remove from front, return element and new queue
    Option<Tuple2<T, Queue<T>>> dequeueOption(); // Safe dequeue operation
}

/**
 * Priority queue with heap-based implementation
 */
class PriorityQueue<T> implements Queue<T> {
    static <T extends Comparable<? super T>> PriorityQueue<T> empty();
    static <T> PriorityQueue<T> empty(Comparator<? super T> comparator);
    static <T extends Comparable<? super T>> PriorityQueue<T> of(T... elements);
    
    // Priority queue specific operations
    T peek();                          // Get highest priority element
    PriorityQueue<T> enqueue(T element); // Add element maintaining heap property
    Tuple2<T, PriorityQueue<T>> dequeue(); // Remove highest priority element
    
    // Merge operation
    PriorityQueue<T> merge(PriorityQueue<T> that);
}

/**
 * Compact set for non-negative integers
 */
class BitSet implements SortedSet<Integer> {
    static BitSet empty();
    static BitSet of(int... ints);
    static BitSet ofAll(Iterable<Integer> ints);
    
    // BitSet specific operations
    BitSet add(int value);             // Add integer to set
    BitSet remove(int value);          // Remove integer from set
    BitSet union(BitSet that);         // Bitwise OR
    BitSet intersect(BitSet that);     // Bitwise AND
    BitSet complement();               // Bitwise NOT (finite range)
    
    // Range operations
    static BitSet range(int from, int toExclusive);
    int min();                         // Smallest element
    int max();                         // Largest element
}

Install with Tessl CLI

npx tessl i tessl/maven-io-vavr--vavr

docs

collections.md

concurrent.md

control-types.md

core-types.md

functional-interfaces.md

index.md

tile.json