I'm trying to add an object to a Hashset within a Hashmap.
Here gamesAndTeams is a Hashmap, and it contains a Hashset.
I've looked over some tutorials over the web but what I'm trying isn't working.
Am I doing something wrong?
Match newmatch = new Match(dateOfGame, stad, guestTeam, hostTeam, hostGoals, guestGoals);
gamesAndTeams.put(key, gamesAndTeams.get(key).add(newmatch));
You must first check if the key is present in the HashMap. If not, you should create the value HashSet and put it in the HashMap :
if (gamesAndTeams.containsKey(key))
gamesAndTeams.get(key).add(newmatch);
else {
HashSet<Match> set = new HashSet<>();
gamesAndTeams.put(key,set);
set.add(newmatch);
}
or
HashSet<Match> set = gamesAndTeams.get(key);
if (set == null) {
set = new HashSet<>();
gamesAndTeams.put(key,set);
}
set.add(newmatch);
Yes.
Assuming gamesAndTeams already has an entry for key, you just want
gamesAndTeams.get(key).add(newmatch);
...you don't need to put anything in the map unless it was previously not in the map at all.
Related
I'm checking to see if a key in my HashMap exists, if it does, I also want to check to see if any other keys have a value with the same name as that of the original key I checked for or not.
For example I have this.
System.out.println("What course do you want to search?");
String searchcourse = input.nextLine();
boolean coursefound = false;
if(hashmap.containsKey(searchcourse) == true){
coursefound = true;
}
This checks to see if the key exists in my hashmap, but now I need to check every single key's values for a specific value, in this case the string searchcourse.
Usually I would use a basic for loop to iterate through something like this, but it doesn't work with HashMaps. My values are also stored in a String ArrayList, if that helps.
You will want to look at each entry in the HashMap. This loop should check the contents of the ArrayList for your searchcourse and print out the key that contained the value.
for (Map.Entry<String,ArrayList> entries : hashmap.entrySet()) {
if (entries.getValue().contains(searchcourse)) {
System.out.println(entries.getKey() + " contains " + searchcourse);
}
}
Here are the relevant javadocs:
Map.Entry
HashMap entrySet method
ArrayList contains method
You can have a bi-directional map. E.g. you can have a Map<Value, Set<Key>> or MultiMap for the values to keys or you can use a bi-directional map which is planned to be added to Guava.
As I understand your question, the values in your Map are List<String>. That is, your Map is declares as Map<String, List<String>>. If so:
for (List<String> listOfStrings : myMap.values()) [
if (listOfStrings .contains(searchcourse) {
// do something
}
}
If the values are just Strings, i.e. the Map is a Map<String, String>, then #Matt has the simple answer.
I need to save two depending Strings (action and parameter) into a file or a hashtable/map or an Array, depending what is the best solution for speed and memory.
My Application iterates through a large amount of forms on a website and i want to skip if the combination (String action,String parameter) already was tested and therefore saved. I thing an Array would be too slow if I have more then thousands of different action and parameter tupels. I´m not experienced enough to chose the right method for this. I tried a hashtable but it does not work:
Hashtable<String, String> ht = new Hashtable<String, String>();
if (ht.containsKey(action) && ht.get(action).contains(parameter)) {
System.out.println("Tupel already exists");
continue;
}
else
ht.put(action, parameter);
If a action and parameter will always be a 1-to-1 mapping (an action will only ever have one parameter), then your basic premise should be fine (though I'd recommend HashMap over Hashtable as it's faster and supports null keys)
If you will have many parameters for a given action, then you want Map<String, Set<String>> - where action is the key and each action is then associated with a set of parameters.
Declare it like this:
Map<String, Set<String>> map = new HashMap<>();
Use it like this:
Set<String> parameterSet = map.get(action); // lookup the parameterSet
if ((parameterSet != null) && (parameterSet.contains(parameter)) { // if it exists and contains the key
System.out.println("Tupel already exists");
} else { // pair doesn't exist
if (parameterSet == null) { // create parameterSet if needed
parameterSet = new HashSet<String>();
map.put(action, parameterSet);
}
parameterSet.add(parameter); // and add your parameter
}
As for the rest of your code and other things that may not be working:
I'm not sure what your use of continue is for in your original code; it's hard to tell without the rest of the method.
I'm assuming the creation of your hashtable is separated from the usage - if you're recreating it each time, then you'll definitely have problems.
I have a HashSet of Strings in the format: something_something_name="value"
Set<String> name= new HashSet<String>();
Farther down in my code I want to check if a String "name" is included in the HashSet. In this little example, if I'm checking to see if "name" is a substring of any of the values in the HashSet, I'd like it to return true.
I know that .contains() won't work since that works using .equals(). Any suggestions on the best way to handle this would be great.
With your existing data structure, the only way is to iterate over all entries checking each one in turn.
If that's not good enough, you'll need a different data structure.
You can build a map (name -> strings) as follows:
Map<String, List<String>> name_2_keys = new HashMap<>();
for (String name : names) {
String[] parts = key.split("_");
List<String> keys = name_2_keys.get(parts[2]);
if (keys == null) {
keys = new ArrayList<>();
}
keys.add(name);
name_2_keys.put(parts[2], keys);
}
Then retrieve all the strings containing the name name:
List<String> keys = name_2_keys.get(name)
You can keep another map where name is the key and something_something_name is the value.
Thus, you would be able to move from name -> something_something_name -> value. If you want a single interface, you can write a wrapper class around these two maps, exposing the functionality you want.
I posted a MapFilter class here a while ago.
You could use it like:
MapFilter<String> something = new MapFilter<String>(yourMap, "something_");
MapFilter<String> something_something = new MapFilter<String>(something, "something_");
You will need to make your container into a Map first.
This would only be worthwhile doing if you look for the substrings many times.
Is there a way to add a key to a HashMap without also adding a value? I know it seems strange, but I have a HashMap<String, ArrayList<Object>> amd I want to first be able to create keys as needed and then check if a certain key exists and, if so, put the appropriate value, namely the ArrayList<Object>
Was that confusing enough?
Since you're using a Map<String, List<Object>>, you're really looking for a multimap. I highly recommend using a third-party library such as Google Guava for this - see Guava's Multimaps.
Multimap<String, Object> myMultimap = ArrayListMultimap.create();
// fill it
myMultimap.put("hello", "hola");
myMultimap.put("hello", "buongiorno");
myMultimap.put("hello", "สวัสดี");
// retrieve
List<String> greetings = myMultimap.get("hello");
// ["hola", "buongiorno", "สวัสดี"]
Java 8 update: I'm no longer convinced that every Map<K, SomeCollection<V>> should be rewritten as a multimap. These days it's quite easy to get what you need without Guava, thanks to Map#computeIfAbsent().
Map<String, List<Object>> myMap = new HashMap<>();
// fill it
myMap.computeIfAbsent("hello", ignored -> new ArrayList<>())
.addAll(Arrays.asList("hola", "buongiorno", "สวัสดี");
// retrieve
List<String> greetings = myMap.get("hello");
// ["hola", "buongiorno", "สวัสดี"]
I'm not sure you want to do this. You can store null as a value for a key, but if you do how will be able to tell, when you do a .get("key") whether the key exists or if it does exist but with a null value? Anyway, see the docs.
You can put null values. It is allowed by HashMap
You can also use a Set initially, and check it for the key, and then fill the map.
Yes, it was confusing enough ;) I don't get why you want to store keys without values instead just putting empty arraylists instead of null.
Adding null may be a problem, because if you call
map.get("somekey");
and receive a null, then you do not know, if the key is not found or if it is present but maps to null...
//This program should answer your questions
import java.util.*;
public class attemptAddingtoHashMap { //Start of program
//MAIN METHOD #################################################
public static void main(String args[]) { //main begins
Map<String, ArrayList<Object>> hmTrial = new HashMap<String, ArrayList<Object>>();
ArrayList alTrial = new ArrayList();//No values now
if (hmTrial.containsKey("first")) {
hmTrial.put("first", alTrial); }
else {hmTrial.put("first",alTrial);}
//in either case, alTrial, an ArrayList was mapped to the string "first"
//if you choose to, you can also add objects to alTrial later
System.out.println("hmTrial is " + hmTrial); //empty now
alTrial.add("h");
alTrial.add("e");
alTrial.add("l");
alTrial.add("l");
alTrial.add("o");
System.out.println("hmTrial is " + hmTrial);//populated now
} //end of main
//#############################################################################################################
} //end of class
//Note - removing objects from alTrial will remove the from the hashmap
//You can copy, paste and run this code on https://ide.geeksforgeeks.org/
I have a hashmap that is 101 keys in size, but I know for sure about 6 of those have no data inside, and there may be more without data as well. What exactly is inside the empty indexes? Is it null? or is there a Hash(index).isEmpty() method that I can use to see if its empty?
I realize there is a isEmpty method inside hashmap, but I thought that only checked if the entire map was empty not just a single index.
I realize there is a isEmpty method
inside hashmap, but I thought that
only checked if the entire map was
empty not just a single index.
I think what you're looking for is the containsKey(Object) method. According to the documentation:
Returns true if this map contains a
mapping for the specified key. More
formally, returns true if and only if
this map contains a mapping for a key
k such that (key==null ? k==null :
key.equals(k)). (There can be at most
one such mapping.)
Parameters:
key - key whose presence in this map is to be tested
Returns:
true if this map contains a mapping for the specified key
Well, for the keys to arrive there with no data, you have to put them there.
If you did map.put(key, null) then yes the data for that key is null. You always have to give the second parameter to the method, you can't just map.put(key).
If you know for sure that a certain key should have no data you could try going into debug mode and putting a watch for myMap.get(myEmptyKey) and see what you get (in case that no data is an empty object or something else, you should be able to see that).
Edit: Some code would be useful to help you, but if I understand correctly you do something like this:
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
map.put("X", obj);
else if (matchesCriteriaY(obj)) {
map.put("Y", obj);
}
}
Well, if you do that and try to do map.get("X"), but you never actually put anything for that key (becaus no object matched criteria X), you will most definitely get back a null.
On the other hand, if you did something like
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
map.add("X", new ArrayList<Object>());
map.add("Y", new ArrayList<Object>());
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
List<Object> list = map.get("X");
list.add(obj);
else if (matchesCriteriaY(obj)) {
List<Object> list = map.get("Y");
list.add(obj);
}
}
then you could check if a category is empty by doing map.get("x").isEmpty() since List has that method (and it would be empty if no object matched the key criteria).
Judging from what you said, I'm suspecting something like this:
Map<SomeKey, List<SomeValue>> yourMap;
If this is the case, what you can do is
if( yourMap.contains(someKey) ){
List<SomeValue> someList = yourMap.get(someKey);
if(someList.size() == 0){
// it's empty, do something?
}
}