HashMap如何只包含一个条目/对象?

时间:2012-01-12 20:01:24

标签: java hashmap

我希望HashMap只有一个键值对象。

我创建了以下HashMap

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

在HashMap中,我想只有一个条目/对象。 密钥类型是Integer。 值类型是String。

  

e.g。 =&lt; 1,&#34; foo.txt&#34;&gt;

每当我在文件中找到特定单词时,我想

  1. 增加键中的计数器

  2. 在值

  3. 中添加新文件

    e.g。让我们说我正在搜索“#Hello;&#34;在DocsCollection中, 我必须存储每个字样&#34; Hello&#34;术语频率并将新文件连接到先前的值。

      

    &LT; 3,&#34; foo.txt的,hello.txt的,test.txt的&#34;&GT;

    3意味着我找到了这个词&#34; Hello&#34;在三个文件中。

    ,Value包含找到单词的文件

    如果我使用put方法,则会在HashMap中创建一个新条目,导致密钥更改。 它不稳定。它始于&#34; 1&#34;但是当我第二次找到单词时,键会递增,然后put方法会插入一个带有新键的新条目 但我想只有一个条目并修改密钥。 可以这样做吗? 我怎样才能在HashMap中只有一个对象并且每次都修改密钥?

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

    先谢谢

10 个答案:

答案 0 :(得分:23)

尝试这种方式:

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

此地图无法修改,如果你想这样做只是这样做:

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

答案 1 :(得分:6)

地图方法可能不是最好的。问题是你正在改变你的关键值。

请注意,拥有List<String>可能更好,每次匹配时,只需将文件添加到列表中即可。您可以使用list.size()

轻松获得点数

答案 2 :(得分:5)

我会尝试为我认为你的任务提出一些不同的解决方案:

  • 你有单词(hello等)
  • 您想要计算
  • 中找到的文件数量
  • 您想知道文件

您可以使用MultiMap(番石榴):

  • map.put("hello", "file1.txt"); map.put("hello", "file2.txt");
  • map.keys().count("hello") - 获取每个单词的找到次数
  • map.get("hello")会返回包含该字词的所有文件的Collection<String>

你可以在地图中拥有尽可能多的单词。如果你需要每个地图一个条目,你需要X个地图的X地图。

答案 3 :(得分:2)

您是否需要使用HashMap?你可以只有一个int(用于计数)和一个String或StringBuffer(用于文件名)并更新它们。

或者,您可以在每次找到内容时添加文件名。要获取计数,请使用List.size()。但是我看到@hvgotcodes已经用这个想法打败了我。

答案 4 :(得分:2)

你并没有真正使用HashMap可以这么说:你的计数器并不是真正的关键。

根据您的解释,您似乎需要Object表示搜索结果,例如:

public class SearchResult {
     private String searchedWord;
     private long counter;
     private List<String> containingFiles;
     // ...
}

答案 5 :(得分:1)

这是一个使用单个键/值的地图的想法:创建地图,添加单个键值对,然后使用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()方法确定找到单词的文件数。

答案 6 :(得分:1)

确保您想要的工作:

  1. 将值声明为List<String>
  2. 删除原始键/值对,并在每次找到单词时将其替换为新内容。
  3. 类似的东西:

    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);
    }
    

答案 7 :(得分:1)

不是好的方法。

尝试改为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());

答案 8 :(得分:1)

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");

注意这是完全迟钝的&gt;。&lt;

使用vakimshaar的解决方案;)

答案 9 :(得分:0)

从历史上看,标准 Java 提供的标准数据结构很少。 Apache Collections 已在许多场合被结合使用,以添加我们认为缺少的这些额外数据结构。我认为这里的 OP 案例是这些漏洞之一。是的,HashMap 不是正确的方法,并且问题被 OP 建模错误。

对于 Map 中的一个键值对的情况,通常这正是我们所需要的:Pair 或更一般的 Tuple。如果对于我们需要的数据结构的每个实例,“键”和“值”通常都具有相同的数据类型,这将非常有效。

我将参考 this SO question(它本身是重复的,尽管有很多很好的信息)历史上人们如何在 Java 中使用元组。可以使用的补充类的一个例子是 org.apache.commons.lang3.tuple