Фильтровать MultiMap<Предикат, значение>
Block - это несколько долгоживущих экземпляров, представляющих типы, например, A Minecraft BlockType grass, green_wool и т. Д.
Я пытаюсь найти DataStructure, которая может эффективно хранить и тестировать данный BlockPattern (например, портал обсидиана, Wither и т. Д., Если вы знакомы с Minecraft), но если вы не знакомы, то могу создать класс, который может тест для данной структуры, построенной из блоков в данном Vector3i относительно размещаемого блока.
Vector3i представляет собой целочисленный вектор "где" в "блочном шаблоне", которому может соответствовать данный предикат.
например, у вас может быть предикат, который проверяет произвольное свойство блока "hotness", которое проверяет истину для огня и лавы.
Поэтому вместо того, чтобы каждый раз сканировать весь шаблон, чтобы убедиться, что позиции блоков в мире соответствуют предикатам, я думал о том, чтобы решить проблему.
Кэшируйте потенциальные позиции, которые Блок может иметь в шаблоне в мультикарте, и получайте все потенциальные позиции, чтобы ограничить количество проверок, которые происходят впоследствии.
Итак, у меня есть Multimap<Predicate<Block>,Vector3i>
PatternLookup кеш.
Который представляет потенциальные позиции, которые блоку можно найти в BlockPattern.
Таким образом, игрок размещает Блок, мне нужно отфильтровать Multimap, собирая все возможные местоположения, в которых блоку "разрешено" (предикат true) находиться.
Однако в качестве шага оптимизации я подумал, что может быть быстрее протестировать только те предикаты, которые имеют потенциальное совпадение (с точки зрения идентичности). (3 года спустя я не уверен, верно ли это предположение)
Как я могу отфильтровать содержимое мультикарты, чтобы получить коллекцию значений, используя функциональные возможности guava? (или мне лучше просто перебрать EntrySet
?)
например
1 ответ
Вы могли бы использовать Multimaps.filterEntries()
, что-то вроде:
public static <V> Multimap<Predicate<V>, V> filterByPredicateKey(
Multimap<Predicate<V>, V> multimap) {
return Multimaps.filterEntries(multimap, e -> e.getKey().apply(e.getValue()));
}
Это не совсем соответствует сигнатуре мультикарты, которую вы упоминаете в своем вопросе, но я предполагаю block
а также Vector3i
связаны каким-то образом, иначе вы не можете применить предикат к значениям в любом случае.
Это возвращает представление резервной мультикарты, которая свободна (O (1)) для построения, но применяет фильтрацию во время доступа, поэтому .get()
на возвращенном мультикарте есть O (n). В зависимости от ожидаемых вариантов использования вы можете предпочесть скопировать эту мультикарту в отдельную неизменяемую мультикарту, чтобы фильтрация выполнялась только один раз.