Retrieving objects from a Map - java

Guys, this is silly, but i got to ask
You have a private Map<String, String> dbMap = new HashMap<String, String>();
i am putting stuff in after having read the file like:
while ((line = br.readLine()) != null) {
...
int ix = line.indexOf("=");
String key = line.substring(0, ix);
String value = line.substring(ix + 1, line.length());
...
dbMap.put(key, value);
}
Once we done, you print it and your map shows what's inside
System.out.println(fc.getDbMap().keySet());
{MAX_DB_CONNECTIONS = something, DATABASE_PASSWD = something else}
when i try to get value assigned to particular key, i get null, when indeed key exists
Why?
System.out.println(fc.getDbMap().containsKey("DATABASE_PASSWD"));
false
System.out.println(fc.getDbMap().get("DATABASE_PASSWD"));
null

You are printing out keySet() and NOT the Map (as per code), so your keys look like "MAX_DB_CONNECTIONS = something" etc (or maybe the whole thing is key) -- yet you expect keys to be "MAX_DB_CONNECTIONS".
So you are building your Map incorrectly (or library you are asking to fill it).
If these are read from a property file, perhaps you are using wrong separator?

Related

How do I handle duplicate keys in HashMaps in Java?

I have a HashMap. I wrote a method for reading files and printing them, but I just thought that HashMap does not tolerate duplicate keys in the file, so I need to do something about it, e.g. saving the same key but with some kind of a character in the end (like just _ or something like that so they differ from each other). I can't come up with the solution (maybe I could catch an exception of just write an if-block). Could you please help me?
public static HashMap<String, String> hashmapReader(File test3) {
HashMap<String, String> data = new HashMap<>();
try (BufferedReader hmReader = new BufferedReader(new FileReader(test3))) {
String line;
while ((line = hmReader.readLine()) != null) {
String[] columns = line.split("\t");
String key = columns[0];
String value = columns[1];
data.put(key, value);
}
} catch (Exception e) {
System.out.println("Something went wrong");
}
return data;
}
You can add a control on the key if it already exist in the HashMap data.
In order to do this you can use get(key) method of the HashMap Java Class which returns null if the key doesn't exist:
if(data.get(key) != null)
key = key + "_";
data.put(key, value); //adding the split line array to the ArrayList
If it already exists (didn't return null) then you can change his name by adding a character at the end, e.g. "_" as you said.
EDIT: The answer above mine pointed out to me a fact: "What if there are more than 2 identical keys?".
For this reason, I recommend following his solution instead of mine.
To achieve what you actually ask for:
Before your put line:
while (data.containsKey(key)) key += "_";
data.put(key, value);
This will keep on checking the map to see if key already exists, and if it does, it adds the _ to the end, and tries again.
You can do these two lines in one:
while (data.putIfAbsent(key, value) != null) key += "_";
This does basically the same, but it just avoids having to look up twice in the case that the key isn't found (and thus the value should be inserted).
However, consider whether this is actually the best thing to do: how will you then look up things by "key", if you've essentially made up the keys while reading them.
You can keep multiple values per key by using a value type which stores multiple values, e.g. List<String>.
HashMap<String, List<String>> data = new HashMap<>();
// ...
data.computeIfAbsent(key, k -> new ArrayList<>()).add(value);

How to split next entryset iterator?

Hello I'm trying to split next iterator entryset from hashmap but I can't get it to work.
I have an hashmap in which I put two things, first one is sender, second one is channel:
channelList = HashMap()
channelList.put(playername, channelname) #have on mind that those can be changed, depending on what user types in
I have this iterator:
it = channelList.entrySet().iterator()
next = it.next()
But when I print next out it has "=" between arguments from hashmap. For example, if playername is PLAYER and channel name is balkan I get as result: PLAYER=balkan. Question is, how do I get ONLY PLAYERNAME on every next. I tried splitting it like this, but it's not working:
next = it.next()
realnext = next.split("=")
realrealnext = realnext.split("=")[0]
Have on mind that I check for every next using this while loop:
while it.hasNext():
Thanks in advance, Amar!
P.S. I'm jython/python programmer.
The problem is you're casting java.util.Map.Entry to a String. Try this instead
#!/usr/bin/jython
import java.util.HashMap
channelList = java.util.HashMap()
channelList.put("Hello", "World")
it = channelList.entrySet().iterator()
while (it.hasNext()):
e = it.next()
print("key = " + e.getKey())
print("value = " + e.getValue())
Which on my system runs as follows -
$ ./test.py
key = Hello
value = World
$
You shouldn't name reference to Map ....List, it is confusing. You should name it channelMap.
Next, your Maps should use generic types to set up elements they are using, like for example
Map<String, Channel> channelMap = new HashMap<>();
This way you would be able to safely use
Iterator<Entry<String, Channel>> it = channelMap.entrySet().iterator();
and have access to it.next().getKey() (notice that order of elements in HashMap is based on hashCode if its Key so don't be surprised with order like Player2, Player1, Player 3).
Anyway if you just want to iterate over all keys then maybe
for (String key: channelMap.keySet()){
System.out.println(key);
}
would be better solution.

My arraylist is only outputting the last value

I created a HashMap to store a text file with the columns of information. I compared the key to a specific name and stored the values of the HashMap into an ArrayList. When I try to println my ArrayList, it only outputs the last value and leaves out all the other values that match that key.
This isn't my entire code just my two loops that read in the text file, stores into the HashMap and then into the ArrayList. I know it has something to do with my loops.
Did some editing and got it to output, but all my values are displayed multiple times.
My output looks like this.
North America:
[ Anguilla, Anguilla, Antigua and Barbuda, Antigua and Barbuda, Antigua and Barbuda, Aruba, Aruba, Aruba,
HashMap<String, String> both = new HashMap<String, String>();
ArrayList<String> sort = new ArrayList<String>();
//ArrayList<String> sort2 = new ArrayList<String>();
// We need a try catch block so we can handle any potential IO errors
try {
try {
inputStream = new BufferedReader(new FileReader(filePath));
String lineContent = null;
// Loop will iterate over each line within the file.
// It will stop when no new lines are found.
while ((lineContent = inputStream.readLine()) != null) {
String column[]= lineContent.split(",");
both.put(column[0], column[1]);
Set set = both.entrySet();
//Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
if(me.getKey().equals("North America"))
{
String value= (String) me.getValue();
sort.add(value);
}
}
}
System.out.println("North America:");
System.out.println(sort);
System.out.println("\n");
}
Map keys need to be unique. Your code is working according to spec.
if you need to have many values for a key, you may use
Map<key,List<T>>
here T is String (not only list you can use any collection)
Some things seems wrong with your code :
you are iterating on the Map EntrySet to get just one value (you could just use the following code :
if (both.containsKey("North America"))
sort.add(both.get("North America"));
it seems that you can have "North America" more than one time in your input file, but you are storing it in a Map, so each time you store a new value for "North America" in your Map, it will overwrite the current value
I don't know what the type of sort is, but what is printed by System.out.print(sort); is dependent of the toString() implementation of this type, and the fact that you use print() instead of println() may also create problems depending on how you run your program (some shells may not print the last value for instance).
If you want more help, you may want to provide us with the following things :
sample of the input file
declaration of sort
sample of output
what you want to obtain.

Can you reference a java variable from a string?

Hi I have a strange question about java. I will leave out the background info so as not to complicate it. If you have a variable named fname. And say you have a function returning a String that is "fname". Is there a way to say reference the identifier fname via the String "fname". The idea would be something like "fname".toIdentifier() = value but obviously toIdentifier isn't a real method.
I suppose a bit of background mite help. Basically I have a string "fname" mapped to another string "the value of fname". And I want a way to quickly say the variable fname = the value of the key "fname" from the map. I'm getting the key value pair from iterating over a map of cookies in the form . And I don't want to do "if key = "fname" set fname to "value of fname" because I have a ton of variables that need to be set that way. I'd rather do something like currentkey.toIdentifer = thevalue. Weird question maybe I'm overlooking a much easier way to approach this.
Why don't you just use a simple hashmap for this?
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("fname", "someValue");
...
String value = mapping.get(key); //key could be "fname"
In a way you're describing what reflection is used for:
You refer to an object's fields and methods by name.
Java Reflection
However, most of the time when people ask a question like this, they're better off solving their problem by re-working their design and taking advantage of data structures like Maps.
Here's some code that shows how to create a Map from two arrays:
String[] keyArray = { "one", "two", "three" };
String[] valArray = { "foo", "bar", "bazzz" };
// create a new HashMap that maps Strings to Strings
Map<String, String> exampleMap = new HashMap<String, String>();
// create a map from the two arrays above
for (int i = 0; i < keyArray.length; i++) {
String theKey = keyArray[i];
String theVal = valArray[i];
exampleMap.put(theKey, theVal);
}
// print the contents of our new map
for (String loopKey : exampleMap.keySet()) {
String loopVal = exampleMap.get(loopKey);
System.out.println(loopKey + ": " + loopVal);
}
Here's a link to the JavaDoc for Map.

How to Iterate Through Multiple Maps

So essentially, I have two hashmaps, one containing the following values:
rId33=image23
rId32=image22
rId37=image2
And the other containing this data:
{image2.jpeg=C:\Documents and Settings\image2.jpeg, image22.jpeg=C:\Documents and Settings\image22.jpeg, image23.jpeg=C:\Documents and Settings\image23.jpeg}
I basically want to be able to iterate through the first map, find a match of the key's, if a match is found, get the associated value, then look in the second map, find a match in the keys, then pull out the associated value (meaning the file path).
I was thinking of doing something like this for example (the follow is simplified)...
String val2 = "rId33";
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
//enter code here
}
}
I was looking at the methods available for something like .getValue or something, but I'm not entirely sure how to do that. Any help would be appreciated. Thanks in advance for any replies.
Edited Code with Help From Bozho
else if ("v:imagedata".equals(qName) && headingCount > 0)
{
val2 = attributes.getValue("r:id");
String rID = imageMap.get(val2);
String path = imageLocation.get(rID + ".jpeg");
for (String rels: imageMap.keySet())
{
if (rels.contains(val2))
{
inImage = true;
image docImage = new image();
imageCount++;
docImage.setRelID(val2);
docImage.setPath(path);
addImage(docImage);
}
}
From what I see you don't need to iterate. Just:
String value1 = map1.get(key1);
if (value1 != null) {
String path = map2.get(value1 + ".jpeg");
}
If you don't always know whether it's value1 + ".jpeg", but you just know that the key starts with the first value, then you can iterate the 2nd map with:
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key2 = entry.getKey();
String value2 = entry.getValue();
if (key.startsWith(value1)) {
return value2;
}
}
But note that the first code snippet is O(1) (both operations take constant time), while the 2nd is O(n)
And to answer the question as it is formulated in the title:
Get the iterators of both maps, and use it1.next() and it2.next() within a while loop. If any of the maps doesn't have more elements (it.hasNext()) - break.
That seems very inefficient. The entire point of a hash map is to do fast lookups. Do you really need to use that contains call on rID? In other words, can you change your hash map so that it directly contains the verbatim strings you want to search for and not just strings that contain the strings you want to search for as substrings? If yes, you could then use the answer given already. If not and if you must work with these data structures for whatever reason, the way to do what you're trying to do is something like:
String val2 = "rId33";
String path;
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
path = secondMap.get(map.get(rID)+".jpeg");
break;
}
}
if (path == null)
{
//value not found
}

Categories