Как HashMap может состоять только из одной записи / объекта? - PullRequest
12 голосов
/ 13 января 2012

Я хотел бы иметь HashMap только с одним объектом значения ключа.

Я создал следующее HashMap:

    HashMap <Integer,String>DocsCollection = new HashMap <Integer,String>();

В HashMap я хотел бы иметь только одну запись / объект. Тип ключа - целое число. Тип значения - Строка.

например. = <1, "foo.txt">

Каждый раз, когда я нахожу определенное слово в файле, я бы хотел

  1. Увеличение счетчика в ключе

  2. Добавить новый файл в значение

например. Допустим, я ищу слово «Hello» в DocsCollection, Я должен хранить для каждого появления слова «Hello» термин «частота» и объединять новый файл с предыдущим значением.

<3, "foo.txt, hello.txt, test.txt">

3 означает, что я нашел слово «Hello» в трех файлах.

и Значение состоит из файлов, в которых было найдено слово

Если я использую метод put, в HashMap создается новая запись, вызывающая изменения ключа. Это не стабильно. Он начинается с «1», но когда я нахожу слово во второй раз, ключ увеличивается, а затем метод put вставляет новую запись с новым ключом Но я хотел бы иметь только одну запись и изменить ключ. Можно ли это сделать? Как я могу иметь только один объект в HashMap и каждый раз изменять ключ?

   DocsCollection.put(2,"foo.txt,hello.txt"); 

Спасибо, заранее

Ответы [ 9 ]

23 голосов
/ 05 августа 2013

Попробуйте так:

DocsCollection = Collections.singletonMap(2, "foo.txt,hello.txt");

эта карта не может быть изменена, если вы хотите, чтобы это просто сделать:

DocsCollection = Collections.singletonMap(3, "foo.txt,hello.txt");
6 голосов
/ 13 января 2012

Подход к карте может быть не лучшим. Проблема в том, что вы меняете значение ключа.

Обратите внимание, что может быть лучше иметь List<String>, и каждый раз, когда вы подходите к слову, просто добавьте файл в список. Вы можете легко получить счет с list.size()

5 голосов
/ 13 января 2012

Я постараюсь предложить несколько иное решение, как мне кажется, ваша задача:

  • у вас есть слова (hello и т. Д.)
  • вы хотите посчитать, сколько файлов найдено в
  • вы хотите знать файлы

Для этого вы можете использовать MultiMap (гуава):

  • map.put("hello", "file1.txt"); map.put("hello", "file2.txt");
  • map.keys().count("hello") - возвращает количество раз, которое найдено каждое слово
  • map.get("hello") возвращает Collection<String>, содержащий все файлы для этого слова

И на этой карте может быть сколько угодно слов. Если вам нужна одна запись на карту, вам понадобится X карт для X слов.

2 голосов
/ 13 января 2012

Вы на самом деле не используете, так сказать, HashMap: ваш счетчик на самом деле не ключ.

В соответствии с вашими объяснениями вам нужно Object, представляющее результат вашего поиска, например:

public class SearchResult {
     private String searchedWord;
     private long counter;
     private List<String> containingFiles;
     // ...
}
2 голосов
/ 13 января 2012

Есть ли причина, по которой вам нужно использовать HashMap? Вы можете просто использовать int (для подсчета) и String или StringBuffer (для имен файлов) и обновлять их.

Кроме того, у вас может быть список, в который вы добавляете имя файла каждый раз, когда что-то обнаруживается. Чтобы получить количество, используйте List.size (). Но я вижу, что @hvgotcodes уже превзошел меня этой идеей.

1 голос
/ 13 января 2012
public class YourClass {
    private HashMap<Integer, String> occurrences = new HashMap<Integer, String>(1);

    public void addFile(String name) {
        int count = 0;
        String names = "";

        if(occurrences.size() > 0) {
            count = (int)(occurrences.keySet().toArray()[0]);
            names = occurrences.get(count);
            names += ",";
        }

        count++;
        names += name;
        occurrences.remove(count);
        occurrences.put(count, names);
    }
}

когда вы находите файл (назовем его hello.txt), и, скажем, вы находитесь в YourClass, когда находите его, вы делаете:

addFile("hello.txt");

обратите внимание, что это очень умственно отсталый>. <</p>

иди с решением Вакимшаара;)

1 голос
/ 13 января 2012

Не очень хороший путь.

Вместо этого попробуйте Map<String, Set<String>>, где ключом является ключевое слово, а значением является набор файлов, в которых вы нашли ключевое слово. Добавление к нему будет выглядеть так:

//further up
final Map<String, Set<String>> map = new HashMap<String, Set<String>>();

//then:
public void addRef(final String keyword, final String filename)
{
    if (!map.containsKey(keyword)) // keyword not encountered yet
        map.put(keyword, new HashSet<String>());

    map.get(keyword).add(filename);
}

Тогда вы сможете собирать информацию с этой карты, когда возникнет такая необходимость. В частности, чтобы собрать количество файлов, в которых было найдено ключевое слово, необходимо:

for (final String keyword: map.keySet())
    System.out.printf("%s was encountered %d time(s)\n",
        keyword, map.get(keyword).size());
1 голос
/ 13 января 2012

Чтобы убедиться, что то, что вы хотите, работает:

  1. Объявите значение равным List<String>.
  2. Удалите исходную пару ключ / значение и замените ее новым содержимымкаждый раз, когда вы нашли слово.

Что-то вроде:

HashMap<Integer, List<String>> map = new HashMap<Integer, List<String>>();
// some loop
if(/* new word found */) {
   Integer key = (Integer)map.keySet().toArray()[0];
   List<String> value = (List<String>)map.get(key);
   value.add(word);
   map.remove(key);
   map.put((key + 1), value);
}
1 голос
/ 13 января 2012

Вот идея иметь карту с одним ключом / значением: создайте карту, добавьте одну пару ключ-значение, а затем сделайте ее неизменяемой, используя Collections.unmodifiableMap(). Таким образом, никакие другие элементы не могут быть добавлены на карту. Как это:

HashMap<Integer, String> docsCollection = new HashMap<Integer, String>();
docsCollection.put(2, "foo.txt,hello.txt");
docsCollection = Collections.unmodifiableMap(docsCollection);

Это работает только , если вы заранее знаете ключ / значение; после вызова unmodifiableMap карта фактически заморожена, и вы не сможете добавлять / удалять другие элементы из нее.

Теперь, что вы спрашиваете в вопросе: не подходит для использования карты, это неправильная структура данных для использования в этом случае. Вам лучше иметь ArrayList<String>, добавить к нему имена файлов, в которых было найдено слово, и использовать метод списка size() для определения количества файлов, в которых было найдено слово.

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