Java, самый быстрый способ определить, соответствуют ли какие-либо значения в hashmap значению? - PullRequest
5 голосов
/ 19 апреля 2011

Извините моего новичка в Java, так как я недостаточно опытен, чтобы знать, как наиболее эффективно это сделать.У меня есть хэш-карта, как показано ниже, но он будет содержать 40000 записей:

Map <String, String> someHashmap = new HashMap <String, String> ();
someHashmap.put("filepath1", null);
someHashmap.put("filepath2", "tag1");
someHashmap.put("filepath3", "tag2");

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

Ответы [ 4 ]

12 голосов
/ 19 апреля 2011

Вы можете использовать метод containsValue, который гласит:

Возвращает значение true, если эта карта отображает один или несколько ключей на указанное значение.

somHashmap.containsValue(null);

Однако имейте в виду, что если у вас большой набор данных (и, кажется, у вас есть), вы должны создать отдельную структуру данных, чтобы отслеживать значения, которые позволяют O (1) искать время,а не O (n) время, как предлагается в других ответах.

4 голосов
/ 19 апреля 2011

Вот альтернативное решение, рассчитанное на скорость.

Назовите ваш оригинальный HashMap a. Есть второй HashMap<String, Integer> aCount. На хэш-карте aCount будет храниться подсчет количества каждого значения в вашей исходной хеш-карте.

Каждый раз, когда вы вставляете ключ k и значение v в первый HashMap, проверьте, если aCount.containsKey(v). Если это так, то увеличьте значение: aCount.put(v, aCount.get(v) + 1). В противном случае добавьте новую запись: aCount.put(v, 1).

Каждый раз, когда вы удаляете ключ k и значение v из первого HashMap, проверьте счет с помощью aCount.get(v). Если число больше единицы, используйте aCount.put(v, aCount.get(v) - 1), чтобы уменьшить его. В противном случае (т. Е. Количество точно равно одному) используйте aCount.remove(v).

Тогда вам нужно всего лишь позвонить по номеру aCount.contains(v), чтобы узнать, есть ли указанное значение в вашей HashMap a.

Зачем все это? Потому что таким образом, вместо того, чтобы иметь время запроса O (n), чтобы выяснить, существует ли значение в вашем HashMap, вы получаете время O (1). Если это ценно для вас, то вышеприведенное решение будет работать. Если это не имеет значения для вас, вы можете легко использовать ответ Майка Льюиса.

0 голосов
/ 19 апреля 2011

Поскольку вас интересует только null, каждый раз, когда вы put вводите HashMap, вы можете проверить, является ли значение null, и сохранить key в HashSet.

*.1008 * Тогда вам нужно позаботиться о синхронизации всех CRUD с карты <-> HashSet
0 голосов
/ 19 апреля 2011

Если вам действительно нужна скорость, вам необходимо сохранить используемые значения в HashSet, помимо HashMap. Например (не проверено!).

public class MapWithVals<K, V> extends HashMap<K, V> {

    protected final Set<V> vals = new HashSet<V>();

    public MapWithVals() {
        super();
    }

    public MapWithVals(Map<? extends K, ? extends V> m) {
        super(m);
        vals.addAll(m.values());
    }

    @Override
    public void clear() {
        super.clear();
        vals.clear();
    }

    @Override
    public V put(K arg0, V arg1) {
        vals.add(arg1);
        return super.put(arg0, arg1);
    }


    @Override
    public V remove(Object arg0) {
        V val = get(arg0);
        super.remove(arg0);
        if( ! super.containsValue(val) ) vals.remove(val);
        return val;
    }

    @Override
    public boolean containsValue(Object value) {
        return vals.contains(value);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> arg0) {
        super.putAll(arg0);
        vals.addAll(arg0.values());
    }

    @Override
    public Object clone() {
        throw new RuntimeException("not implemented");
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...