GenericTimeSeries implements Function<T, V>, Iterable<Pair<T, V>> { public V apply(T x) { int i = binarySearch(times, x, cmp); i = (0 <= i) ? i : -i - 2; return get(i).getSecond(); } GenericTimeSeries(Iterator<Pair<T, V>> timestamps);  GenericTimeSeries(Iterable<Pair<T, V>> timestamps);  GenericTimeSeries(Iterator<T> t, Function<T, V> f); static GenericTimeSeries<T, List<V>> merge(Iterable<GenericTimeSeries<T, V>> ts); static GenericTimeSeries<T, V> merge(Iterable<GenericTimeSeries<T, V>> ts, BinaryOperator<V> op); static GenericTimeSeries<T, U> merge(GenericTimeSeries<T, V> tv, GenericTimeSeries<T, V> tw, BiFunction<V, V, U> f); int size(); Pair<T, V> get(int i); GenericTimeSeries<T, V> relocate(Iterator<T> t); V apply(T x); boolean sameLeg(T a, T b); GenericTimeSeries<T, V> subSeries(T a, T b); Iterator<Pair<T, V>> iterator(); void addAttribute(String attribute, Object value); Object getAttribute(String attribute); Iterator<Map.Entry<String, Object>> getAttributes(); @Override boolean equals(Object x); @Override int hashCode();  }
@Test public void testApply() { List<Pair<Integer, Integer>> ts = new ArrayList<>(); ts.add(pairOf(null, null)); ts.add(pairOf(null, null)); ts.add(pairOf(null, null)); ts.add(pairOf(null, null)); ts.add(pairOf(0, 9)); ts.add(pairOf(0, 8)); ts.add(pairOf(0, 7)); ts.add(pairOf(10, 17)); ts.add(pairOf(20, 27)); GenericTimeSeries<Integer, Integer> sf = new GenericTimeSeries<>(ts); assertEquals(sf.size(), 4); assertEquals(sf.apply(null), null); assertEquals(sf.apply(-1), null); assertEquals(sf.apply(0), Integer.valueOf(7)); assertEquals(sf.apply(1), Integer.valueOf(7)); assertEquals(sf.apply(10), Integer.valueOf(17)); assertEquals(sf.apply(11), Integer.valueOf(17)); assertEquals(sf.apply(20), Integer.valueOf(27)); assertEquals(sf.apply(10000), Integer.valueOf(27)); ts = new ArrayList<>(); ts.add(pairOf(null, -7)); ts.add(pairOf(0, 7)); ts.add(pairOf(10, 17)); ts.add(pairOf(20, null)); sf = new GenericTimeSeries<>(ts); assertEquals(sf.apply(-10000), Integer.valueOf(-7)); assertNull(sf.apply(20)); assertNull(sf.apply(10000)); ts = new ArrayList<>(); ts.add(pairOf(null, -7)); ts.add(pairOf(0, 70)); ts.add(pairOf(10, 170)); ts.add(pairOf(10, 180)); ts.add(pairOf(10, 190)); ts.add(pairOf(10, 200)); ts.add(pairOf(20, 200)); ts.add(pairOf(30, 200)); ts.add(pairOf(40, null)); ts.add(pairOf(50, null)); ts.add(pairOf(60, null)); sf = new GenericTimeSeries<>(ts); assertEquals(sf.apply(-10000), Integer.valueOf(-7)); assertEquals(sf.apply(0), Integer.valueOf(70)); assertEquals(sf.apply(10), Integer.valueOf(200)); assertEquals(sf.apply(30), Integer.valueOf(200)); assertEquals(sf.apply(35), Integer.valueOf(200)); assertNull(sf.apply(40)); assertNull(sf.apply(40000)); ts = takeAll(sf.iterator()); assertEquals(ts.size(), 4); }