[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/support/sorted-dict/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# SortedDict

`SortedDict<K, V>` is a `java.util.TreeMap<K, V>` that keeps its entries sorted by key. It's the type of [`Worktime.dates`](<https://docs.dhtmlx.com/planning-engine/java/api/data/worktime.md#dates>), where the keys are [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) values. A new `Worktime` already holds an empty `SortedDict`, so you usually fill that map in place with `put`. To build one yourself, call a constructor.

## Declaration

```java
public class SortedDict<K, V> extends TreeMap<K, V> implements Iterable<Map.Entry<K, V>>
```

Every `TreeMap`, `NavigableMap` and `Map` method works as usual. The members below are the ones the class adds.

## Constructors

### SortedDict()

```java
public SortedDict()
```

Creates an empty map that orders keys by their natural ordering. The keys must implement `Comparable`, as `Moment` does.

### SortedDict(Map)

```java
public SortedDict(Map<K, V> m)
```

Creates a map with the entries of `m`, ordered by the keys' natural ordering. The map doesn't keep the comparator of `m`, even when `m` is a `SortedMap`.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `m` | `Map<K, V>` | Entries to copy |

### SortedDict(Comparator)

```java
public SortedDict(Comparator<K> c)
```

Creates an empty map that orders keys with `c`.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `c` | `Comparator<K>` | Key ordering |

## Methods

### iterator

```java
public Iterator<Map.Entry<K, V>> iterator()
```

Iterates over `entrySet()` in key order. Because of this method, a `SortedDict` works directly in a for-each loop: `for (Map.Entry<K, V> e : dict)`.

**Returns** an iterator over the entries.

### add

```java
public void add(K k, V v)
```

Adds an entry when the key isn't in the map yet.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `k` | `K` | Key |
| `v` | `V` | Value |

**Errors** throws `IllegalArgumentException` (`duplicate key`) when the map already contains `k`. The map stays unchanged. Use `put` to replace an existing entry.

### tryGetValue

```java
public boolean tryGetValue(K k, Ref<V> out)
```

Looks up `k` and writes the result to `out.value`.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `k` | `K` | Key to look up |
| `out` | [`Ref<V>`](<https://docs.dhtmlx.com/planning-engine/java/api/support/ref.md>) | Receives the value, or `null` when the key is missing |

**Returns** `true` when the map contains `k`.

### getValueOrDefault

```java
public V getValueOrDefault(K k)
```

Same as `get(k)`.

**Returns** the value for `k`, or `null` when the key is missing.

### toDictionary

```java
public <A, B> Dict<A, B> toDictionary(Fn1<Map.Entry<K, V>, A> key, Fn1<Map.Entry<K, V>, B> val)
```

Builds a new map from the entries, with keys and values produced by the two functions. `Fn1` is a functional interface, so lambdas work for both arguments.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `key` | `Fn1<Map.Entry<K, V>, A>` | Produces the key of each new entry |
| `val` | `Fn1<Map.Entry<K, V>, B>` | Produces the value of each new entry |

**Returns** a `Dict<A, B>`, a `LinkedHashMap` subclass. It keeps the entries in this map's key order. When two entries produce the same key, the later entry wins. Wrap the result in `new SortedDict<>(...)` to get a sorted map back.

## Example

```java
import org.dhtmlx.plen.*;
import java.util.List;
import java.util.Map;

public class HolidayDates {
    public static void main(String[] args) throws Exception {
        Worktime worktime = new Worktime();
        SortedDict<Moment, DayRule> dates = worktime.dates;

        dates.add(Moment.fromYmdHm(2026, 12, 25, 0, 0), new DayRule.Off());
        dates.add(Moment.fromYmdHm(2026, 12, 24, 0, 0),
            new DayRule.Hours(List.of(new TimeRange(8 * 60, 12 * 60))));

        Ref<DayRule> rule = new Ref<>();
        if (dates.tryGetValue(Moment.fromYmdHm(2026, 12, 25, 0, 0), rule)) {
            System.out.println(rule.value);              // Off{}
        }

        for (Map.Entry<Moment, DayRule> e : dates) {     // Dec 24 first, then Dec 25
            System.out.println(e.getKey() + " -> " + e.getValue());
        }
    }
}
```

## Related

- [`Worktime`](<https://docs.dhtmlx.com/planning-engine/java/api/data/worktime.md#dates>) - the field that holds a `SortedDict`
- [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) - the key type of the date exceptions
- [`Ref<T>`](<https://docs.dhtmlx.com/planning-engine/java/api/support/ref.md>) - the out parameter of `tryGetValue`
- [Working time and calendars](<https://docs.dhtmlx.com/planning-engine/java/scheduling/working-time-calendars.md#date-exception-keys>) - date exception keys
