Comparing HashMaps for Matches and Mismatches - java

I have two HashMaps that is expected to hold Keys which are identical, but expect some differences on their values, and perhaps source/target does not contain the key.
Map<String, Double> source = repository.getSourceData();
Map<String, Double> target = repository.getTargetData();
I'm looking to produce a report with Matched data values for the keys, Mismatched data values for keys, and finally Keys exist in only one map.
Using Java 8's computeIfPresent() or computeIfAbsent(), how can I achieve this? I need to iterate through source map, check if a key exists in the target map, if exists, inspect values are matching or not. when matched, output result to matched collection. when mismatched, output to mismatched container, and finally output no key exists in target.

I don't think computeIfPresent or computeIfAbsent are appropriate for this:
Map<String, Double> source = repository.getSourceData();
Map<String, Double> target = repository.getTargetData();
Map <String, Double> matched = new HashMap<>();
Map <String, List<Double>> mismatched = new HashMap<>();
Map <String, String> unmatched = new HashMap<>();
for (String keySource : source.keySet()) {
Double dblSource = source.get(keySource);
if (target.containsKey(keySource)) { // keys match
Double dblTarget = target.get(keySource);
if (dblSource.equals(dblTarget)) { // values match
matched.put(keySource, dblSource);
} else { // values don't match
mismatched.put(keySource, new ArrayList<Double>(Arrays.toList(dblSource, dblTarget)));
}
} else { // key not in target
unmatched.put(keySource, "Source");
}
}
for (String keyTarget : target.keySet()) { // we only need to look for unmatched
Double dblTarget = target.get(keyTarget);
if (!source.containsKey(keyTarget)) {
unmatched.put(keyTarget, "Target");
}
}
// print out matched
System.out.println("Matched");
System.out.println("=======");
System.out.println("Key\tValue");
System.out.println("=======");
for (String key : matched.keySet()) {
System.out.println(key + "\t" + matched.get(key).toString());
}
// print out mismatched
System.out.println();
System.out.println("Mismatched");
System.out.println("=======");
System.out.println("Key\tSource\tTarget");
System.out.println("=======");
for (String key : mismatched.keySet()) {
List<Double> values = mismatched.get(key);
System.out.println(key + "\t" + values.get(0) + "\t" + values.get(1));
}
// print out unmatched
System.out.println();
System.out.println("Unmatched");
System.out.println("=======");
System.out.println("Key\tWhich\tValue");
System.out.println("=======");
for (String key : unmatched.keySet()) {
String which = unmatched.get(key);
Double value = null;
if ("Source".equals(which)) {
value = source.get(key);
} else {
value = target.get(key);
}
System.out.println(key + "\t" + which + "\t" + value);
}

Related

Processing the particular key value pair in set of key value pairs in java

The string can be
"accountno=18&username=abc&password=1236" or "username=abc&accountno=18&password=1236" or the accountno can be present anywhere in the string.
I need to get the accountno details from this string using a key value pair. I used spilt on "&" but I'm unable to get the result.
import java.util.regex.*;
public class RegexStrings {
public static void main(String[] args) {
String input = "accountno=18&username=abc&password=1236";
String exten = null;
Matcher m = Pattern.compile("^accountno: (.&?)$", Pattern.MULTILINE).matcher(input);
if (m.find()) {
exten = m.group(1);
}
System.out.println("AccountNo: "+exten);
}
}
How can I get the accountno value from this above string as key value pair in java
You may handle this by first splitting on & to isolate each key/value pair, then iterate that collection and populate a map:
String input = "accountno=18&username=abc&password=1236";
String[] parts = input.split("&");
Map<String, String> map = new HashMap<>();
for (String part : parts) {
map.put(part.split("=")[0], part.split("=")[1]);
}
System.out.println("account number is: " + map.get("accountno"));
This prints:
account number is: 18
Using some simple tools, like string.split and Map, you can easly do that:
Map<String, String> parse(String frase){
Map<String, String> map = new TreeMap<>();
String words[] = frase.aplit("\\&");
for(String word : words){
String keyValuePair = word.split("\\=");
String key = keyValuePair[0];
String value = keyValuePair[1];
map.put(key, value);
}
return map;
}
To get a specific value, like "accountno", just retrive that key map.get("accountno")
The same answer mentioned by #vinicius can be achieved using Java 8 by :
Map<String, String> map = Arrays.stream(input.split("&"))
.map(str -> str.split("="))
.collect(Collectors.toMap(s -> s[0],s -> s[1]));
//To retrieve accountno from map
System.out.println(map.get("accountno"));
As you said
the accountno can be present anywhere in the string
String input = "accountno=18&username=abc&password=1236";
//input = "username=abc&accountno=19&password=1236";
Matcher m = Pattern.compile("&?accountno\\s*=\\s*(\\w+)&?").matcher(input);
if (m.find()) {
System.out.println("Account no " + m.group(1));
}
This would work even when accountno is somewhere in the middle of the string
Output:
Account no 18
You can try out regex here:
https://regex101.com/r/nOHmzc/2

How to Loop next element in hashmap

I have a set of strings like this
A_2007-04, A_2007-09, A_Agent, A_Daily, A_Execute, A_Exec, B_Action, B_HealthCheck
I want output as:
Key = A, Value = [2007-04,2007-09,Agent,Execute,Exec]
Key = B, Value = [Action,HealthCheck]
I'm using HashMap to do this
pckg:{A,B}
count:total no of strings
reports:set of strings
Logic I used is nested loop:
for (String l : reports[i]) {
for (String r : pckg) {
String[] g = l.split("_");
if (g[0].equalsIgnoreCase(r)) {
report.add(g[1]);
dirFiles.put(g[0], report);
} else {
break;
}
}
}
I'm getting output as
Key = A, Value = [2007-04,2007-09,Agent,Execute,Exec]
How to get second key?
Can someone suggest logic for this?
Assuming that you use Java 8, it can be done using computeIfAbsent to initialize the List of values when it is a new key as next:
List<String> tokens = Arrays.asList(
"A_2007-04", "A_2007-09", "A_Agent", "A_Daily", "A_Execute",
"A_Exec", "P_Action", "P_HealthCheck"
);
Map<String, List<String>> map = new HashMap<>();
for (String token : tokens) {
String[] g = token.split("_");
map.computeIfAbsent(g[0], key -> new ArrayList<>()).add(g[1]);
}
In terms of raw code this should do what I think you are trying to achieve:
// Create a collection of String any way you like, but for testing
// I've simply split a flat string into an array.
String flatString = "A_2007-04,A_2007-09,A_Agent,A_Daily,A_Execute,A_Exec,"
+ "P_Action,P_HealthCheck";
String[] reports = flatString.split(",");
Map<String, List<String>> mapFromReportKeyToValues = new HashMap<>();
for (String report : reports) {
int underscoreIndex = report.indexOf("_");
String key = report.substring(0, underscoreIndex);
String newValue = report.substring(underscoreIndex + 1);
List<String> existingValues = mapFromReportKeyToValues.get(key);
if (existingValues == null) {
// This key hasn't been seen before, so create a new list
// to contain values which belong under this key.
existingValues = new ArrayList<>();
mapFromReportKeyToValues.put(key, existingValues);
}
existingValues.add(newValue);
}
System.out.println("Generated map:\n" + mapFromReportKeyToValues);
Though I recommend tidying it up and organising it into a method or methods as fits your project code.
Doing this with Map<String, ArrayList<String>> will be another good approach I think:
String reports[] = {"A_2007-04", "A_2007-09", "A_Agent", "A_Daily",
"A_Execute", "A_Exec", "P_Action", "P_HealthCheck"};
Map<String, ArrayList<String>> map = new HashMap<>();
for (String rep : reports) {
String s[] = rep.split("_");
String prefix = s[0], suffix = s[1];
ArrayList<String> list = new ArrayList<>();
if (map.containsKey(prefix)) {
list = map.get(prefix);
}
list.add(suffix);
map.put(prefix, list);
}
// Print
for (Map.Entry<String, ArrayList<String>> entry : map.entrySet()) {
String key = entry.getKey();
ArrayList<String> valueList = entry.getValue();
System.out.println(key + " " + valueList);
}
for (String l : reports[i]) {
String[] g = l.split("_");
for (String r : pckg) {
if (g[0].equalsIgnoreCase(r)) {
report = dirFiles.get(g[0]);
if(report == null){ report = new ArrayList<String>(); } //create new report
report.add(g[1]);
dirFiles.put(g[0], report);
}
}
}
Removed the else part of the if condition. You are using break there which exits the inner loop and you never get to evaluate the keys beyond first key.
Added checking for existing values. As suggested by Orin2005.
Also I have moved the statement String[] g = l.split("_"); outside inner loop so that it doesn't get executed multiple times.

How to get value from Map key in java

I am trying to receive message attributes from Amazon SQS with the following code :
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
}
and it returns the output:
project - {StringValue: 25,StringListValues: [],BinaryListValues: [],DataType: String}
I want to get only the value 25. How do I do that?
Try this:
attributes.get("project").getStringValue()
References:
How to extract from a Map the value of a given key?
How to extract a String Value of a given MessageAttributeValue?
Because that's the object of value type com.amazonaws.services.sqs.model.MessageAttributeValue declared in your Map .
You need to get the value out of that object like the way you would normally do :
for(String key: attributes.keySet()){
com.amazonaws.services.sqs.model.MessageAttributeValue object = attributes.get(key);
//some method to get that 25 value
System.out.println(key + " - "+ object.getStringValue());
}
You need to loop on your map here is an example to show you how to get the values of the map:
I have a : Map<String, Object> map = new HashMap<String, Object>();
for (Entry<String, Object> entry : map.entrySet()) {
System.out.println("entry key : "+entry.getKey());
System.out.println("Object value :"+entry.getValue());
}
use this (library org.json.JSONObject; [java-json.jar])
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
try {
JSONObject json = new JSONObject(attributes.get(key));
System.out.println(json.get("StringValue"));
} catch (JSONException e) {
e.printStackTrace();
}
}

How can I get a column of value from hashmap

I have a hashmap listview with four key and multiple value that retrieve from database. For now I can get all the value from the key of FOODID2, FOODNAME2, PRICE2, RATING2 and display via toast. But what I want is just the value from the key (FOODID2) to be display. Is it possible to do it? And correct me if I'm wrong. Thanks!
for (int i=0; i<data.size(); i=i+4)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put(FOODID2, (String) data.get(i));
map.put(FOODNAME2, (String) data.get(i+1));
map.put(PRICE2, (String) data.get(i+2));
map.put(RATING2, (String) data.get(i+3));
LIST2.add(map);
for(Entry<String, String> entry: map.entrySet())
{
if(entry.getKey().equals(FOODID2))
{
Toast.makeText(getApplicationContext(),
"EXISTS " + entry.getKey(), Toast.LENGTH_LONG)
.show();
}
}
}
get entry.getKey() and just validate this
if(entry.getKey().equls("YOUR KEY NAME"))
{
// here u can print the toaste.
}
Why not just map.get(FOODID2)? That is, something like this...
StringBuilder sb = new StringBuilder();
for (HashMap<String, String> map : LIST2) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append("EXISTS " + map.get(FOODID2));
}
you can usehashMap.get(key) to get the value of a particular key.
or in your code you can use a if statement to check for the key.
You can loop map.keySet() to get all the keys, loop map.values() to get all the values.

How to sort a string into a map and print the results

I have a string in the format nm=Alan&hei=72&hair=brown
I would like to split this information up, add a conversion to the first value and print the results in the format
nm Name Alan
hei Height 72
hair Hair Color brown
I've looked at various methods using the split function and hashmaps but have had no luck piecing it all together.
Any advice would be very useful to me.
Map<String, String> aliases = new HashMap<String, String>();
aliases.put("nm", "Name");
aliases.put("hei", "Height");
aliases.put("hair", "Hair Color");
String[] params = str.split("&"); // gives you string array: nm=Alan, hei=72, hair=brown
for (String p : params) {
String[] nv = p.split("=");
String name = nv[0];
String value = nv[1];
System.out.println(nv[0] + " " + aliases.get(nv[0]) + " " + nv[1]);
}
I really do not understand what you problem was...
Try something like this:
static final String DELIMETER = "&"
Map<String,String> map = ...
map.put("nm","Name");
map.put("hei","Height");
map.put("hair","Hair color");
StringBuilder builder = new StringBuilder();
String input = "nm=Alan&hei=72&hair=brown"
String[] splitted = input.split(DELIMETER);
for(Stirng str : splitted){
int index = str.indexOf("=");
String key = str.substring(0,index);
builder.append(key);
builder.append(map.get(key));
builder.append(str.substring(index));
builder.append("\n");
}
A HashMap consists of many key, value pairs. So when you use split, devise an appropriate regex (&). Once you have your string array, you can use one of the elements as the key (think about which element will make the best key). However, you may now be wondering- "how do I place the rest of elements as the values?". Perhaps you can create a new class which stores the rest of the elements and use objects of this class as values for the hashmap.
Then printing becomes easy- merely search for the value of the corresponding key. This value will be an object; use the appropriate method on this object to retrieve the elements and you should be able to print everything.
Also, remember to handle exceptions in your code. e.g. check for nulls, etc.
Another thing: your qn mentions the word "sort". I don't fully get what that means in this context...
Map<String, String> propsMap = new HashMap<String, String>();
Map<String, String> propAlias = new HashMap<String, String>();
propAlias.put("nm", "Name");
propAlias.put("hei", "Height");
propAlias.put("hair", "Hair Color");
String[] props = input.split("&");
if (props != null && props.length > 0) {
for (String prop : props) {
String[] propVal = prop.split("=");
if (propVal != null && propVal.length == 2) {
propsMap.put(propVal[0], propVal[1]);
}
}
}
for (Map.Entry tuple : propsMap.getEntrySet()) {
if (propAlias.containsKey(tuple.getKey())) {
System.out.println(tuple.getKey() + " " + propAlias.get(tuple.getKey()) + " " + tuple.getValue());
}
}

Categories