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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
package bjc.utils.data.lazy;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import bjc.utils.data.IHolder;
import bjc.utils.data.IPair;
import bjc.utils.data.Pair;
/**
* A lazy holder of two values
*
* Lazy variant of {@link IPair}
*
* @author ben
*
* @param <L>
* The type of value stored on the left side of the pair
* @param <R>
* The type of value stored on the right side of the pair
*/
public class LazyPair<L, R> implements IPair<L, R>, ILazy {
/**
* The backing store for this pair
*/
protected IHolder<IPair<L, R>> delegatePair;
private boolean materialized = false;
private boolean pendingActions = false;
/**
* Create a new blank lazy pair
*/
public LazyPair() {
delegatePair = new LazyHolder<>(new Pair<>());
}
/**
* Create a new lazy pair with the specified initial values
*
* @param leftValue
* The initial value for the left side of the pair
* @param rightValue
* The initial value for the right side of the pair
*/
public LazyPair(L leftValue, R rightValue) {
materialized = true;
delegatePair = new LazyHolder<>(new Pair<>(leftValue, rightValue));
}
/**
* Create a new lazy pair with the specified sources for initial values
*
* @param leftValueSource
* The function to call for the left initial value
* @param rightValueSource
* The function to call for the right initial value
*/
public LazyPair(Supplier<L> leftValueSource,
Supplier<R> rightValueSource) {
if (leftValueSource == null || rightValueSource == null) {
throw new NullPointerException("Sources must be non-null");
}
delegatePair = new LazyHolder<>(() -> {
return new Pair<>(leftValueSource.get(),
rightValueSource.get());
});
}
/**
* Create a new lazy pair with a specified internal delegate
*
* @param delegate
* The internal delegate for the pair
*/
private LazyPair(IHolder<IPair<L, R>> delegate, boolean mater,
boolean pend) {
materialized = mater;
pendingActions = pend;
delegatePair = delegate;
}
/*
* (non-Javadoc)
*
* @see bjc.utils.data.IPair#apply(java.util.function.Function,
* java.util.function.Function)
*/
@Override
public <L2, R2> IPair<L2, R2> apply(Function<L, L2> leftTransform,
Function<R, R2> rightTransform) {
if (leftTransform == null || rightTransform == null) {
throw new NullPointerException("Transforms must be non-null");
}
IHolder<IPair<L2, R2>> newPair = delegatePair
.map((currentPair) -> currentPair.apply(leftTransform,
rightTransform));
return new LazyPair<>(newPair, materialized, true);
}
/*
* (non-Javadoc)
*
* @see bjc.utils.data.IPair#doWith(java.util.function.BiConsumer)
*/
@Override
public void doWith(BiConsumer<L, R> action) {
if (action == null) {
throw new NullPointerException("Action must be non-null");
}
pendingActions = true;
delegatePair.doWith((currentPair) -> {
currentPair.doWith(action);
});
}
/*
* (non-Javadoc)
*
* @see bjc.utils.data.IPair#merge(java.util.function.BiFunction)
*/
@Override
public <E> E merge(BiFunction<L, R, E> merger) {
if (merger == null) {
throw new NullPointerException("Merger must be non-null");
}
materialized = true;
pendingActions = false;
return delegatePair
.unwrap((currentPair) -> currentPair.merge(merger));
}
@Override
public boolean isMaterialized() {
return materialized;
}
@Override
public boolean hasPendingActions() {
return pendingActions;
}
/*
* Note: Materializing will also apply all currently pending actions
*/
@Override
public void materialize() {
merge((left, right) -> null);
materialized = true;
pendingActions = false;
}
@Override
public void applyPendingActions() {
merge((left, right) -> null);
materialized = true;
pendingActions = false;
}
@Override
public <L2, R2> IPair<L2, R2> bind(
BiFunction<L, R, IPair<L2, R2>> binder) {
// TODO Auto-generated method stub
IHolder<IPair<L2, R2>> newDelegate = delegatePair
.map((pairVal) -> {
return pairVal.bind(binder);
});
return new LazyPair<>(newDelegate, isMaterialized(),
hasPendingActions());
}
}
|