1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package bjc.functypes;
import java.util.*;
import java.util.function.Function;
import bjc.funcdata.Freezable;
import bjc.funcdata.ObjectFrozen;
/**
* Functional interface for a generic builder using a map
*
* @author bjcul
*
* @param <K> Key type of the map
* @param <V> Value type of the map
* @param <R> Result type of the builder
*/
public interface MapBuilder<K, V, R> extends Freezable<MapBuilder<K, V, R>> {
/**
* Build an instance using the current map
*
* @return An instance constructed using the map
*/
R build();
/**
* Add a value to the map
*
* @param key The key to add
* @param value The value to add
*
* @return The builder, for chaining
*/
MapBuilder<K, V, R> add(K key, V value);
/**
* Remove a value from the map
*
* @param key The key to remove
*
* @return The removed value
*/
V remove(K key);
/**
* Clear the contents of the map
*/
void clear();
/**
* Get the internal map.
*
* @return The internal map
*/
Map<K, V> getMap();
/**
* Create a new map-builder from a function
*
* @param <K> The key type of the map
* @param <V> The value type of the map
* @param <R> The result of the builder
*
* @param f The building function
*
* @return A map-builder using the function
*/
static <K, V, R> MapBuilder<K, V, R> from(Function<Map<K, V>, R> f) {
return new FunctionalMapBuilder<>(f);
}
}
final class FunctionalMapBuilder<K, V, R> implements MapBuilder<K, V, R> {
private final Function<Map<K, V>, R> f;
private Map<K, V> mep = new HashMap<>();
private boolean frozen = false;
FunctionalMapBuilder(Function<Map<K, V>, R> f) {
this.f = f;
}
@Override
public R build() {
return f.apply(mep);
}
@Override
public MapBuilder<K, V, R> add(K key, V value) {
if (frozen) throw new ObjectFrozen();
mep.put(key, value);
return this;
}
@Override
public V remove(K key) {
if (frozen) throw new ObjectFrozen();
return mep.remove(key);
}
@Override
public void clear() {
if (frozen) throw new ObjectFrozen();
mep.clear();
}
@Override
public Map<K, V> getMap() {
if (frozen) return Collections.unmodifiableMap(mep);
return mep;
}
@Override
public boolean freeze() {
frozen = true;
return true;
}
@Override
public boolean thaw() {
frozen = false;
return true;
}
@Override
public boolean isFrozen() {
return frozen;
}
}
|