Эффективный способ исключить конкретное значение из TreeMap

1

Я пытаюсь добиться максимальной производительности для своего приложения. В какой-то момент кода я хочу получить все значения с карты, кроме той, которая соответствует определенному ключу.

Теперь, если бы я хотел получить все значения, я бы использовал это:

map.values();

и полагая, что класс TreeMap создан эффективно, метод "values ()" просто возвращает refference so → O (1).

В моем случае, хотя я хочу исключить значение определенного ключа. Этот код:

Set<String> set = new ...
for (String key: map.keySet()) {
   if (!key.equals("badKey")) {
      set.add(map.get(key));
   }
}

имеет сложность N * (logN), которая намного медленнее начального O (1), и это вызвано необходимостью удаления только одного значения.


Есть лучший способ сделать это?

  • 0
    как часто эта карта меняется, т.е. вы кладете / удаляете с карты?
  • 1
    В первом случае вы получаете коллекцию <String>. Во втором вы получите TreeMap <String, String>. Итак, что вы на самом деле хотите в результате? Что вы делаете с возвращенной коллекцией или картой?
Показать ещё 7 комментариев
Теги:
data-structures
treemap

3 ответа

2
Лучший ответ

Вы можете использовать entrySet вместо keySet. Таким образом, O (1) потребовалось бы выяснить, принадлежит ли данное значение ключу, который вы хотите исключить.

Вы можете вызвать entrySet любое время, когда вам нужно перебирать значения, и исключить "плохую" клавишу во время итерации по ним. Это даст вам такую же сложность, как и итерация над values() Collection.

  • 0
    Спасибо, это то, что я искал!
2

Как насчет этого?

map.entrySet().stream()
  .filter(e -> !e.getKey().equals(keyToFilter))
  .map(Map.Entry::getValue);

Завершите с помощью forEach или toCollection(Collectors.TO_SET) или просто верните поток.

Извините, если код не компилируется точно, он из памяти, и я не коснулся API-интерфейсов java 8 через несколько месяцев, но вы должны получить дрейф. ;)

  • 0
    Не уверен, что OP ищет решение Java 8. Вопрос специально помечен как java.
  • 0
    @bot 8 - это текущая Java. Кажется, у тебя это с ног на голову.
Показать ещё 7 комментариев
1

Вы можете создать набор из map.values() и после удаления значения "badKey" из этого набора.

Set<String> set = new HashSet<String>(map.values());
String badValue = map.get("badKey");
set.remove(badValue);
  • 0
    Это тоже работает ... Это ограничивает вас в использовании HashSet для оптимальной производительности - я хочу, чтобы все было отсортировано так: TreeSet - но это довольно хорошее решение даже с TreeSet. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню