0
# Collection Ordering
1
2
Annotations for specifying ordering behavior in generated sorted collections, supporting both natural and reverse ordering. These annotations control how collection attributes are handled when using sorted collection types like `SortedSet` and `NavigableMap`.
3
4
## Capabilities
5
6
### Natural Ordering
7
8
Specify natural ordering for sorted collections using element's natural comparison.
9
10
```java { .api }
11
/**
12
* Apply natural ordering to sorted collections.
13
* Elements will be ordered using their natural comparison order
14
* (Comparable implementation). This is the default behavior for
15
* sorted collections, but can be made explicit with this annotation.
16
*/
17
@Target(ElementType.METHOD)
18
@Retention(RetentionPolicy.SOURCE)
19
@interface Value.NaturalOrder {}
20
```
21
22
**Usage Example:**
23
24
```java
25
import org.immutables.value.Value;
26
import java.util.SortedSet;
27
import java.util.NavigableSet;
28
import java.util.SortedMap;
29
30
@Value.Immutable
31
public interface UserProfile {
32
String username();
33
34
@Value.NaturalOrder
35
SortedSet<String> tags(); // Tags sorted alphabetically
36
37
@Value.NaturalOrder
38
NavigableSet<Integer> scores(); // Scores sorted numerically (ascending)
39
40
@Value.NaturalOrder
41
SortedMap<String, String> metadata(); // Keys sorted alphabetically
42
}
43
44
// Usage - collections maintain natural ordering
45
UserProfile profile = ImmutableUserProfile.builder()
46
.username("alice")
47
.addTags("developer", "admin", "beta-tester") // Will be sorted: admin, beta-tester, developer
48
.addScores(85, 92, 78, 95) // Will be sorted: 78, 85, 92, 95
49
.putMetadata("role", "developer")
50
.putMetadata("department", "engineering")
51
.putMetadata("level", "senior") // Keys sorted: department, level, role
52
.build();
53
54
// Collections are automatically sorted
55
SortedSet<String> tags = profile.tags();
56
// Iteration order: ["admin", "beta-tester", "developer"]
57
58
NavigableSet<Integer> scores = profile.scores();
59
// Iteration order: [78, 85, 92, 95]
60
```
61
62
### Reverse Ordering
63
64
Specify reverse natural ordering for sorted collections.
65
66
```java { .api }
67
/**
68
* Apply reverse natural ordering to sorted collections.
69
* Elements will be ordered in reverse of their natural comparison order.
70
* Equivalent to using Collections.reverseOrder() comparator.
71
*/
72
@Target(ElementType.METHOD)
73
@Retention(RetentionPolicy.SOURCE)
74
@interface Value.ReverseOrder {}
75
```
76
77
**Usage Example:**
78
79
```java
80
import org.immutables.value.Value;
81
import java.util.SortedSet;
82
import java.util.NavigableSet;
83
import java.util.SortedMap;
84
import java.time.LocalDateTime;
85
86
@Value.Immutable
87
public interface TaskQueue {
88
String name();
89
90
@Value.ReverseOrder
91
SortedSet<Priority> priorities(); // Highest priority first
92
93
@Value.ReverseOrder
94
NavigableSet<LocalDateTime> timestamps(); // Most recent first
95
96
@Value.ReverseOrder
97
SortedMap<Integer, String> rankingsByScore(); // Highest scores first
98
}
99
100
enum Priority implements Comparable<Priority> {
101
LOW, MEDIUM, HIGH, CRITICAL
102
}
103
104
// Usage - collections maintain reverse ordering
105
TaskQueue queue = ImmutableTaskQueue.builder()
106
.name("production-tasks")
107
.addPriorities(Priority.LOW, Priority.CRITICAL, Priority.MEDIUM) // Sorted: CRITICAL, MEDIUM, LOW
108
.addTimestamps(
109
LocalDateTime.of(2023, 1, 1, 10, 0),
110
LocalDateTime.of(2023, 1, 1, 14, 30),
111
LocalDateTime.of(2023, 1, 1, 9, 15)
112
) // Sorted: 14:30, 10:00, 09:15 (most recent first)
113
.putRankingsByScore(85, "alice")
114
.putRankingsByScore(92, "bob")
115
.putRankingsByScore(78, "charlie") // Sorted by key: 92->bob, 85->alice, 78->charlie
116
.build();
117
118
// Collections maintain reverse order
119
SortedSet<Priority> priorities = queue.priorities();
120
// Iteration order: [CRITICAL, MEDIUM, LOW]
121
122
NavigableSet<LocalDateTime> timestamps = queue.timestamps();
123
// Iteration order: [14:30, 10:00, 09:15] (newest first)
124
```
125
126
## Supported Collection Types
127
128
The ordering annotations work with these collection types:
129
130
### Sorted Sets
131
132
```java
133
import org.immutables.value.Value;
134
import java.util.SortedSet;
135
import java.util.NavigableSet;
136
import java.time.LocalDate;
137
import java.math.BigDecimal;
138
139
@Value.Immutable
140
public interface SortedSetExample {
141
@Value.NaturalOrder
142
SortedSet<String> naturalStrings();
143
144
@Value.ReverseOrder
145
SortedSet<Integer> reverseNumbers();
146
147
@Value.NaturalOrder
148
NavigableSet<LocalDate> naturalDates();
149
150
@Value.ReverseOrder
151
NavigableSet<BigDecimal> reverseDecimals();
152
}
153
```
154
155
### Sorted Maps
156
157
```java
158
import org.immutables.value.Value;
159
import java.util.SortedMap;
160
import java.util.NavigableMap;
161
import java.time.LocalDateTime;
162
163
@Value.Immutable
164
public interface SortedMapExample {
165
@Value.NaturalOrder
166
SortedMap<String, Object> naturalKeyMap();
167
168
@Value.ReverseOrder
169
SortedMap<Integer, String> reverseKeyMap();
170
171
@Value.NaturalOrder
172
NavigableMap<LocalDateTime, String> naturalDateMap();
173
174
@Value.ReverseOrder
175
NavigableMap<Double, String> reverseScoreMap();
176
}
177
```
178
179
## Generated Builder Methods
180
181
For ordered collections, the generated builders include specialized methods:
182
183
### Set Builder Methods
184
185
```java { .api }
186
// Generated builder methods for ordered sets
187
public Builder addTags(String element) { ... }
188
public Builder addTags(String... elements) { ... }
189
public Builder addAllTags(Iterable<String> elements) { ... }
190
191
// The elements are automatically ordered according to the annotation
192
```
193
194
### Map Builder Methods
195
196
```java { .api }
197
// Generated builder methods for ordered maps
198
public Builder putMetadata(String key, String value) { ... }
199
public Builder putAllMetadata(Map<String, String> entries) { ... }
200
201
// The entries are automatically ordered by key according to the annotation
202
```
203
204
## Combining with Custom Comparators
205
206
While the annotations handle natural and reverse ordering, you can also define custom comparators:
207
208
```java
209
import org.immutables.value.Value;
210
import java.util.SortedSet;
211
import java.util.TreeSet;
212
import java.util.Comparator;
213
214
@Value.Immutable
215
public interface CustomOrderedData {
216
// Use annotation for simple cases
217
@Value.ReverseOrder
218
SortedSet<String> reverseAlphabetic();
219
220
// Use factory methods for complex ordering
221
static ImmutableCustomOrderedData.Builder builder() {
222
return ImmutableCustomOrderedData.builder();
223
}
224
225
// Custom comparator for complex sorting
226
static SortedSet<Task> createTaskSet() {
227
return new TreeSet<>(
228
Comparator
229
.comparing(Task::priority)
230
.thenComparing(Task::createdAt)
231
.reversed()
232
);
233
}
234
}
235
```
236
237
## Performance Considerations
238
239
- **Natural ordering**: Uses the element's `compareTo` method
240
- **Reverse ordering**: Equivalent to `Collections.reverseOrder()`
241
- **Immutable collections**: Generated code uses efficient immutable sorted collections
242
- **Builder performance**: Elements are sorted once during `build()` call
243
- **Memory efficiency**: Sorted collections share structure when possible
244
245
## Usage with Custom Types
246
247
Ordering annotations work with any `Comparable` type:
248
249
```java
250
@Value.Immutable
251
public interface Event {
252
String name();
253
LocalDateTime timestamp();
254
Priority priority();
255
}
256
257
@Value.Immutable
258
public interface EventLog {
259
@Value.ReverseOrder
260
SortedSet<Event> events(); // Most recent events first (if Event implements Comparable)
261
}
262
263
// Event must implement Comparable for ordering to work
264
// Events will be sorted by their natural order (typically by timestamp or priority)
265
```
266
267
For non-comparable types, you'll need to provide custom comparators in factory methods rather than using the ordering annotations.