# counter

`software.visionary:counter:2026.10.13` · https://codeberg.org/Kompuwiz/counter

Counter: iterators whose values only increase or only decrease

Interfaces for counters: <code>Iterator</code>s whose values only increase or only decrease, over any <code>Comparable</code> type, with no dependencies beyond the JDK.

## Rationale

**Why.** Ticket numbers, attempt counts, version stamps and clocks all issue values in one direction. Code that consumes them needs that direction, not a particular implementation.

**Problem.** A plain <code>Iterator&lt;T&gt;</code> or <code>Supplier&lt;T&gt;</code> says nothing about order, so a caller cannot tell from the type whether the next value can repeat or go back.

**Solution.** The direction is a type. Accept an <code>Increasing.Strict&lt;T&gt;</code> where values must never repeat, or an <code>Increasing&lt;T&gt;</code> where they may repeat but never fall, and the caller may supply any implementation.

## Key Concepts

### Counter

**Role.** An <code>Iterator&lt;T&gt;</code> over <code>Comparable</code> values. <code>hasNext()</code> is true by default, for a counter with no last value; a counter with one overrides it. It is sealed: every counter is <code>Increasing</code> or <code>Decreasing</code>.

### Increasing

**Role.** Each <code>next()</code> is greater than or equal to the one before. <code>Increasing.Strict</code> requires greater, so no value repeats.

### Decreasing

**Role.** Each <code>next()</code> is less than or equal to the one before. <code>Decreasing.Strict</code> requires less, so no value repeats.

## How It Works

**Guarantees.** The interfaces declare an order but cannot enforce it; each implementation must keep it. <code>next()</code> is the one abstract method, so a lambda or method reference can implement <code>Increasing</code>, <code>Decreasing</code> or their <code>Strict</code> subtypes.

**Thread safety.** Thread safety is up to each implementation.

## Lane

**Purpose.** Typing a source of values that only increase or only decrease.

**When to avoid.** Values that may move in either direction: use <code>Iterator</code> or <code>Stream</code>.

## Usage

A strictly increasing counter from a method reference

```java
import java.util.concurrent.atomic.AtomicLong;
import software.visionary.counter.Increasing;

var issued = new AtomicLong();
Increasing.Strict<Long> tickets = issued::getAndIncrement;
System.out.println(tickets.next());
System.out.println(tickets.next());
System.out.println(tickets.hasNext());

```

Output

```text
0
1
true

```

## Dependencies

- `software.visionary:junit-closure:2026.09.17` at Testing

## Caveats

- On a counter with no last value, <code>forEachRemaining</code> never returns, and neither does a stream over it unless it stops early, as <code>limit</code>, <code>takeWhile</code> or <code>findFirst</code> do.

