Вы можете использовать двоичный поиск, чтобы найти первую запись, а затем перебирать список, чтобы найти оставшиеся записи. TreeMap имеет хорошую поддержку для этого, но он отображает только один ключ (один уровень) на одно значение, поэтому вам придется использовать список для значений.
void append(TreeMap<Integer, List<FoodSource>> map, int level, FoodSource source) {
map.putIfAbsent(level, new ArrayList<>());
map.get(level).add(source);
}
TreeMap<Integer, List<FoodSource>> map = new TreeMap<>();
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 12, new FoodSource("foodSource1", 12));
append(map, 15, new FoodSource("foodSource1", 15));
List<FoodSource> sources = map.floorKey(12).getValue();
Однако у Guava есть TreeMultimap это сделает это за вас. Единственная проблема заключается в том, что он сохраняет значения в наборе, а не в списке, поэтому элементы не упорядочиваются на заданном уровне.
TreeMultimap<Integer, FoodSource> map = TreeMultimap.create();
map.put(10, new FoodSource("foodSource1", 10));
map.put(10, new FoodSource("foodSource1", 10));
map.put(12, new FoodSource("foodSource1", 12));
map.put(15, new FoodSource("foodSource1", 15));
Set<FoodSource> sources = map.get(map.keySet().floor(12));
В каждом случае floor
означает получение максимального ключа меньше или равно данному уровню (и может быть заменен на ceiling
, чтобы получить наименьший ключ больше или равный данному уровню).