Reputation: 4901
I would like to have a HashMap
with only one key-value object.
I have created the following HashMap
:
HashMap <Integer,String>DocsCollection = new HashMap <Integer,String>();
In the HashMap I would like to have only one entry/object. The key type is an Integer. The value type is a String.
e.g. = <1,"foo.txt">
Every time I find a specific word in a file I would like to
Increment the counter in key
Add the new file in the value
e.g. Let's say that I'm searching for the word "Hello" in a DocsCollection
,
I have to store for every appearance of the word "Hello" the term frequency and concatenate the new file to the previous value.
<3,"foo.txt,hello.txt,test.txt">
3 means that I've found the word "Hello" in three files.
and the Value consists of the files where the word was found
If I use the method put, a new entry is created in the HashMap
cause the key changes.
It's not stable. It begins with "1" but when I find the word second time , the key increments and then the put method inserts a new entry with a new key
But i would like to have only one entry and modify the key.
Can this be done?
How can i have only one object in a HashMap and modify the key every time?
DocsCollection.put(2,"foo.txt,hello.txt");
Thanks, in advance
Upvotes: 21
Views: 61851
Reputation: 2587
These days one would probably use Map.of(key, value)
/**
* Returns an unmodifiable map containing a single mapping.
* See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
* @param k1 the mapping's key
* @param v1 the mapping's value
* @return a {@code Map} containing the specified mapping
* @throws NullPointerException if the key or the value is {@code null}
*
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1) {
return new ImmutableCollections.Map1<>(k1, v1);
}
Upvotes: 0
Reputation: 9708
There was historically a paucity with the standard provided data structures of standard Java. Apache Collections has been used hand-in-hand on many occasions to add in these additional data structures we felt we were missing. I think the OP case here is one of those holes. And yes the HashMap is not the correct approach and the problem was modeled wrong by the OP.
For the case of one key, value pair in a Map, often that is exactly what we need: a Pair or more generally a Tuple. This works really well if both "the key" and "the value" were to generally have the same data type for each instance of the data structure we need.
I will refer to this SO question (which itself is a duplicate although has a lot of good information) how historically one might use tuples in Java. An example of a supplemental class which can be used is org.apache.commons.lang3.tuple
Upvotes: 0
Reputation: 2048
Try this way:
DocsCollection = Collections.singletonMap(2, "foo.txt,hello.txt");
this Map can't be modified, if you want to to that just do this:
DocsCollection = Collections.singletonMap(3, "foo.txt,hello.txt");
Upvotes: 45
Reputation: 2777
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);
}
}
when you find a file (let's call it hello.txt), and let's say you're in YourClass when you find it, you do:
addFile("hello.txt");
do note that this is utterly retarded >.<
go with vakimshaar's solution ;)
Upvotes: 1
Reputation: 236034
Here's an idea for having a map with a single key/value: create the map, add the single key-value pair, and then make it unmodifiable using Collections.unmodifiableMap()
. In that way, no other elements can be added to the map. Like this:
HashMap<Integer, String> docsCollection = new HashMap<Integer, String>();
docsCollection.put(2, "foo.txt,hello.txt");
docsCollection = Collections.unmodifiableMap(docsCollection);
This works only if you know the key/value beforehand; after the call to unmodifiableMap
the map is effectively frozen and you won't be able to add/remove further elements from it.
Now, what you ask in the question is not suitable for using a map, that's not the correct data structure for using in this case. You'd be better off having an ArrayList<String>
, adding to it the file names where the word was found, and using the list's size()
method for determining the number of files where the word was found.
Upvotes: 1
Reputation: 121750
Not the good way to go.
Try instead a Map<String, Set<String>>
where the key is the keyword and the value is the set of files you found the keyword into. Adding to it will then look like:
//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);
}
Then you'll be able to collect information from this map when the need arises. In particular, to collect the number of files a keyword was found into, you would:
for (final String keyword: map.keySet())
System.out.printf("%s was encountered %d time(s)\n",
keyword, map.get(keyword).size());
Upvotes: 1
Reputation: 62439
To ensure that what you want works:
List<String>
.Something like:
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);
}
Upvotes: 1
Reputation: 597134
I'll try to suggest a bit different solution to what I think your task is:
hello
, etc)You can use a MultiMap
(guava) for that:
map.put("hello", "file1.txt"); map.put("hello", "file2.txt");
map.keys().count("hello")
- gets you the number of times each word is foundmap.get("hello")
returns a Collection<String>
containing all the files for that wordAnd you can have as many words in that map as you like. If you needed one-entry-per-map, you'd need X maps for X words.
Upvotes: 6
Reputation: 53829
You are not really using a HashMap
so to speak : your counter is not really a key.
What you seem to need according to your explanation is an Object
representing the result of your search, such as:
public class SearchResult {
private String searchedWord;
private long counter;
private List<String> containingFiles;
// ...
}
Upvotes: 2
Reputation: 15729
Is there a reason you need to use a HashMap? You could just have an int (for the count) and a String or StringBuffer (for the filenames) and update them.
Alternatively, you could have a List into which you add the filename each time something is found. To get the count, use List.size(). But I see that @hvgotcodes already beat me to the punch with that idea.
Upvotes: 2
Reputation: 120198
The Map approach might not be the best. The issue is you are changing your key value.
Note it might be better to just have a List<String>
, and everytime you match the word, just add the file to the list. You can get the count easily with list.size()
Upvotes: 7