RangeLookupTable { public LookupItem<T, U> getLookupItem(T srcValue) { if (items.isEmpty()) { return null; } else { int lo = 0; int hi = items.size() - 1; while (hi >= lo) { int mid = lo + (hi - lo) / 2; LookupItem<T, U> item = items.get(mid); Range r = item.getRange(); if (r.containsN(srcValue)) { return item; } else if (!Double.isInfinite(r.getMin().doubleValue()) && Double.compare(srcValue.doubleValue(), r.getMin().doubleValue()) <= 0) { hi = mid - 1; } else { lo = mid + 1; } } return null; } } private  RangeLookupTable(Builder builder); LookupItem<T, U> getLookupItem(T srcValue); @Override String toString();  }
@Test public void simpleLookup() throws Exception { Integer[] breaks = { -10, -5, 0, 5, 10 }; Integer[] values = { -99, -1, 0, 1, 2, 99 }; RangeLookupTable<Integer, Integer> table = RangeLookupTest.createTable(breaks, values); final int N = breaks.length; final int startVal = breaks[0] - 1; final int endVal = breaks[N - 1] + 1; int k = 0; int expected = values[0]; LookupItem<Integer, Integer> match; for (int val = startVal; val <= endVal; val++) { if (val >= breaks[k]) { expected = values[k + 1]; if (k < N - 1) k++; } match = table.getLookupItem(val); assertNotNull(match); assertEquals(expected, match.getValue().intValue()); } }
@Test public void addOverlappedRange() throws Exception { builder.add(RangeFactory.create(5, true, 10, true), 1); builder.add(RangeFactory.create(0, true, 20, true), 2); RangeLookupTable<Integer, Integer> table = builder.build(); LookupItem<Integer, Integer> match; for (int val = 0; val <= 20; val++) { int expected = val < 5 || val > 10 ? 2 : 1; match = table.getLookupItem(val); assertNotNull(match); assertEquals(expected, match.getValue().intValue()); } }
@Test public void addCompletelyOverlappedRange() throws Exception { builder.add(RangeFactory.create(0, true, 20, true), 1); builder.add(RangeFactory.create(5, true, 10, true), 2); RangeLookupTable<Integer, Integer> table = builder.build(); for (int val = 0; val <= 20; val++) { LookupItem<Integer, Integer> match = table.getLookupItem(val); assertNotNull(match); assertEquals(1, match.getValue().intValue()); } }
@Test public void lookupWithIntervalGap() throws Exception { builder.add(RangeFactory.create(Double.NEGATIVE_INFINITY, false, -1, false), 1); builder.add(RangeFactory.create(1, false, Double.POSITIVE_INFINITY, false), 1); RangeLookupTable<Integer, Integer> table = builder.build(); assertEquals(1, table.getLookupItem(-2).getValue().intValue()); assertNull(table.getLookupItem(-1)); assertNull(table.getLookupItem(0)); assertNull(table.getLookupItem(1)); assertEquals(1, table.getLookupItem(2).getValue().intValue()); }
@Test public void lookupWithPointGap() throws Exception { builder.add(RangeFactory.create(Double.NEGATIVE_INFINITY, false, 0, false), 1); builder.add(RangeFactory.create(0, false, Double.POSITIVE_INFINITY, false), 1); RangeLookupTable<Integer, Integer> table = builder.build(); assertEquals(1, table.getLookupItem(-1).getValue().intValue()); assertNull(table.getLookupItem(0)); assertEquals(1, table.getLookupItem(1).getValue().intValue()); }