Foreach Key/Value pair issue - java

I'm trying to convert a PHP script into a Java one but coming across a few issues on a foreach loop. In the PHP script I have a foreach that takes the key:value pair and based off this does a str_replace.
foreach ($pValues AS $vKey => $vValue)
$vString = str_replace("{".$vKey."}", "'".$vValue."'", $vString);
I tried replicating this in Java without success. I need to get the key from the array to use in the string replace function, but can't find out where or if it's possible to get the key name from the array passed in.
Is this the right way or am I completely off? Should I be using the ImmutablePair method?
for (String vKey : pValues)
// String replace
Here's hoping there is an easy way to get the key:value pair in Java.

This can be acheived by using Map as data structure and then using entryset for iterating over it.
Map<K,V> entries= new HashMap<>();
for(Entry<K,V> entry : entries.entrySet()){
// you can get key by entry.getKey() and value by entry.getValue()
// or set new value by entry.setValue(V value)
}

That is not possible with a simple foreach-loop in Java.
If pValues is an array, you could use a simple for-loop:
for (int i = 0; i < pValues.length; i++)
// String replace
If pValues is a Map, you can iterate through it like this:
for (Key key : map.keySet())
string.replace(key, map.get(key));

Group Totals
Have the function GroupTotals(strArr) read in the strArr parameter containing key:value pairs where the key is a string and the value is an integer. Your program should return a string with new key:value pairs separated by a comma such that each key appears only once with the total values summed up.
For example: if strArr is ["B:-1", "A:1", "B:3", "A:5"] then your program should return the string A:6,B:2.
Your final output string should return the keys in alphabetical order. Exclude keys that have a value of 0 after being summed up.

Thanks all for the help and advice, I've managed to duplicate the function in Java using Map.
if (pValues != null)
{
Set vSet = pValues.entrySet();
Iterator vIt = vSet.iterator();
while(vIt.hasNext())
{
Map.Entry m =(Map.Entry)vIt.next();
vSQL = vSQL.replace("{" + (String)m.getKey() + "}", "'" + (String)m.getValue() + "'");
vSQL = vSQL.replace("[" + (String)m.getKey() +"]", (String)m.getValue());
}
}

Related

Unsure how this piece of code is doing what it does… .getDescribe()

I'm relatively new to Apex and Java.
Could someone possibly explain this snippet of code?
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (String name : m.keySet()) {
DescribeFieldResult r = m.get(name).getDescribe();
System.debug(r);
}
I know it's getting the Describe information for each field on the Opportunity object, but could someone explain, line by line, how it's doing it?
Cheers!
This is about as basic as it gets when you need to enumerate a map:
Line 1 gets the map, and stores it in variable m
Line 2 iterates over the keys of the map m, using name variable for the value of the key in this iteration
Line 3 gets the item from the map m using name for the key, and calls getDescribe
Line 4 passes the result to System.debug
Line 5 closes the loop
However, this is not the best way of iterating the values, though: a simpler approach would be as follows:
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (SObjectField val : m.values()) {
System.debug(val.getDescribe());
}
For completeness, if you would like to iterate both keys and values, iterate entrySet, like this:
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (Map.Entry<String,SObjectField> e : m.entrySet()) {
// e.getKey() produces the key
// e.getValue() produces its associated value
}
Iterating keys and then retrieving the values in a separate call to get is inefficient.

Iterating over the map and calling another method

I am getting an map as shown below inside a method
Map<Integer, Integer> result1 =jmxService.generateMabc(p1, p2,p3,p4);
now the map result 1 will consists oif key value pair as usal
now i want to iterate over the map one by one , fetch the value of the map
that is both key and value which will be of type integer and convert them into string
and store the string two string variables like shown below
string j = will store the key
string t = will store the value
amd then pass these two parameters to another method call which wil take string
j and string t as parameter once they pass i want j and t to be null so that in next iteration the same process and can be continued till the time map has value c an you please advise how to achieve this, what I have tried is..
for (Map.Entry<Integer, Integer> entry : result1.entrySet())
{
String j, t;
j=entry.getKey();
t= entry.getValue();
abc .callanothermethod(string p1,stringp2, stringj, string t)
j=null;
t=null;
}
please advise what will be the correct appoach to obtain the same.
An Integer is not a String. So j = entry.getKey() doesn't make sense.
You need to transform the Integer into a String (by calling toString() for example):
j = entry.getKey().toString();
You really need to learn to
read the error messages from the compiler, which tell you waht is wrong and where
read the javadoc of the classes you're using, to understand what you can do with them.

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.

I have a query in mongodb and the reference key's are in hashmap list , I need to process a simple query using java in mongodb

mongodb query is db.test.find({"col1":{"$ne":""}}).count(), I have tried many sources to find the solution, the "col1" must be populated from list array, please help me
I have pasted a part of my code
`
List<String> likey = new ArrayList<String>();
for (DBObject o : out.results())
{
likey.add(o.get("_id").toString());
}
Iterator<String>itkey = likey.iterator();
DBCursor cursor ;
//cursor = table.find();
HashMap<String, String> hashmap = new HashMap<String, String>();
while (itkey.hasNext())
{
System.out.println((String)itkey.next());
String keys = itkey.next().toString();
//System.out.println("keys --> "+keys);
String nullvalue = "";
Boolean listone = table.distinct(keys).contains(nullvalue);
hashmap.put(keys, listone.toString());
//System.out.println("distinct --> "+keys+" "+listone);
//System.out.println("proper str --- >"+ '"'+keys+'"');
}
Iterator<String> keyIterator = hashmap.keySet().iterator();
Iterator<String> valueIterator = hashmap.values().iterator();
while (keyIterator.hasNext()) {
//System.out.println("key: " + keyIterator.next());
while (valueIterator.hasNext()) {
//System.out.println("value: " + valueIterator.next());
//System.out.println("Key: " + keyIterator.next() +""+"value: "+valueIterator.next());
String hashkey = valueIterator.next();
}
}
`
When you post code, it helps if you indent it, so it is more readable. As I mentioned to you on another forum, you need to go back and review the Java collection classes, since you have multiple usage errors in the above code.
Here are a few things you need to do to clean up your code:
1) You don't need to use the itkey iterator. Instead, use:
for (String key : likey)
and get rid of all the itkey.next calls. Your current code only processes every second element of the List. The other ones are printed out.
2) Your HashMap will map a key to a Boolean. Is that what you want? You said you want to count the number of non-zero values for the key. So, the line:
Boolean listone = table.distinct(keys).contains(nullvalue);
is almost certainly in error.
3) When you iterate over the HashMap, you don't need the valueIterator. Instead, get the key (either from the keyIterator, or a variable you define using the simpler iterator syntax above), then use the key to get the matching value using hashmap.get(key).
This will not make your code work, but it will clean it up somewhat - at the moment it is difficult to understand what you are intending it to do.

Returning a list of wildcard matches from a HashMap in java

I have a Hashmap which may contain wildcards (*) in the String.
For instance,
HashMap<String, Student> students_;
can have John* as one key. I want to know if JohnSmith matches any elements in students_. There could be several matches for my string (John*, Jo*Smith, etc). Is there any way I can get a list of these matches from my HashMap?
Is there another object I could be using that does not require me to iterate through every element in my collection, or do I have to suck it up and use a List object?
FYI, my collection will have less than 200 elements in it, and ultimately I will want to find the pair that matches with the least amount of wildcards.
It's not possible to achieve with a hasmap, because of the hashing function. It would have to assign the hash of "John*" and the hash of "John Smith" et al. the same value.
You could make it with a TreeMap, if you write your own custom class WildcardString wrapping String, and implement compareTo in such a way that "John*".compareTo("John Smith") returns 0. You could do this with regular expressions like other answers have already pointed out.
Seeing that you want the list of widlcard matchings you could always remove entries as you find them, and iterate TreeMap.get()'s. Remember to put the keys back once finished with a name.
This is just a possible way to achieve it. With less than 200 elements you'll be fine iterating.
UPDATE: To impose order correctly on the TreeSet, you could differentiate the case of comparing two WildcardStrings (meaning it's a comparation between keys) and comparing a WildcardString to a String (comparing a key with a search value).
You can use regex to match, but you must first turn "John*" into the regex equivalent "John.*", although you can do that on-the-fly.
Here's some code that will work:
String name = "John Smith"; // For example
Map<String, Student> students_ = new HashMap<String, Sandbox.Student>();
for (Map.Entry<String, Student> entry : students_.entrySet()) {
// If the entry key is "John*", this code will match if name = "John Smith"
if (name.matches("^.*" + entry.getKey().replace("*", ".*") + ".*$")) {
// do something with the matching map entry
System.out.println("Student " + entry.getValue() + " matched " + entry.getKey());
}
}
You can just iterate your Map without converting it into a list, and use the String matches function, wih uses a regexp.
If you want to avoid the loop, you can use guava like this
#Test
public void hashsetContainsWithWildcards() throws Exception {
Set<String> students = new HashSet<String>();
students.add("John*");
students.add("Jo*Smith");
students.add("Bill");
Set<String> filteredStudents = Sets.filter(students, new Predicate<String>() {
public boolean apply(String string) {
return "JohnSmith".matches(string.replace("*", ".*"));
}
});
assertEquals(2, filteredStudents.size());
assertTrue(filteredStudents.contains("John*"));
assertTrue(filteredStudents.contains("Jo*Smith"));
}

Categories