16
16
import java .util .TreeSet ;
17
17
import java .util .concurrent .atomic .AtomicReference ;
18
18
import java .util .function .BiFunction ;
19
+ import java .util .function .BiPredicate ;
19
20
import java .util .function .Consumer ;
20
21
import java .util .function .Function ;
21
22
import java .util .function .Predicate ;
@@ -214,8 +215,22 @@ public <T, R> LocalDateTimeline<R> combine(final LocalDateTimeline<T> other, fin
214
215
* for å 'redusere' tidslinjen ned til enkleste form før lagring etc.
215
216
*/
216
217
public LocalDateTimeline <V > compress () {
218
+ var factory = new CompressorFactory <V >(Objects ::equals , LocalDateSegment ::new );
217
219
TimelineCompressor <V > compressor = segments .stream ()
218
- .collect (TimelineCompressor ::new , TimelineCompressor ::accept , TimelineCompressor ::combine );
220
+ .collect (factory ::get , TimelineCompressor ::accept , TimelineCompressor ::combine );
221
+
222
+ return new LocalDateTimeline <>(compressor .segmenter );
223
+ }
224
+
225
+ /**
226
+ * Fikser opp tidslinjen ved å slå sammen sammenhengende intervall med "like" verider utover periode.
227
+ * @param e - likhetspredikat for å sammenligne to segment som vurderes slått sammen
228
+ * @param c - konstruktør som tar nytt intervall og gammel verdi og lager et nytt segment
229
+ */
230
+ public LocalDateTimeline <V > compress (BiPredicate <V , V > e , BiFunction <LocalDateInterval , V , LocalDateSegment <V >> c ) {
231
+ var factory = new CompressorFactory <>(e , c );
232
+ TimelineCompressor <V > compressor = segments .stream ()
233
+ .collect (factory ::get , TimelineCompressor ::accept , TimelineCompressor ::combine );
219
234
220
235
return new LocalDateTimeline <>(compressor .segmenter );
221
236
}
@@ -757,6 +772,13 @@ public LocalDateSegment<V> apply(LocalDateInterval di, LocalDateSegment<V> seg)
757
772
static class TimelineCompressor <V > implements Consumer <LocalDateSegment <V >> {
758
773
759
774
private final NavigableSet <LocalDateSegment <V >> segmenter = new TreeSet <>();
775
+ private final BiPredicate <V , V > equals ;
776
+ private final BiFunction <LocalDateInterval , V , LocalDateSegment <V >> construct ;
777
+
778
+ TimelineCompressor (BiPredicate <V , V > e , BiFunction <LocalDateInterval , V , LocalDateSegment <V >> c ) {
779
+ this .equals = e ;
780
+ this .construct = c ;
781
+ }
760
782
761
783
@ Override
762
784
public void accept (LocalDateSegment <V > t ) {
@@ -765,11 +787,11 @@ public void accept(LocalDateSegment<V> t) {
765
787
} else {
766
788
LocalDateSegment <V > last = segmenter .last ();
767
789
if (last .getLocalDateInterval ().abuts (t .getLocalDateInterval ())
768
- && Objects . equals (last .getValue (), t .getValue ())) {
790
+ && equals . test (last .getValue (), t .getValue ())) {
769
791
// bytt ut og ekspander intervall for siste
770
792
segmenter .remove (last );
771
793
LocalDateInterval expandedInterval = last .getLocalDateInterval ().expand (t .getLocalDateInterval ());
772
- segmenter .add (new LocalDateSegment < V > (expandedInterval , last .getValue ()));
794
+ segmenter .add (construct . apply (expandedInterval , last .getValue ()));
773
795
} else {
774
796
segmenter .add (t );
775
797
}
@@ -782,4 +804,18 @@ public void combine(@SuppressWarnings("unused") TimelineCompressor<V> other) {
782
804
783
805
}
784
806
807
+ static class CompressorFactory <V > {
808
+ private final BiPredicate <V , V > equals ;
809
+ private final BiFunction <LocalDateInterval , V , LocalDateSegment <V >> construct ;
810
+
811
+ CompressorFactory (BiPredicate <V , V > e , BiFunction <LocalDateInterval , V , LocalDateSegment <V >> c ) {
812
+ this .equals = e ;
813
+ this .construct = c ;
814
+ }
815
+
816
+ TimelineCompressor <V > get () {
817
+ return new TimelineCompressor <>(equals , construct );
818
+ }
819
+ }
820
+
785
821
}
0 commit comments