Removing hashmap key but getting value in previously saved reference - java

I am using Java 1.7
public static void main(String[] args) {
HashMap<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(1, "a");
String testString = testMap.get(1);
System.out.println("Before remove = " + testString);
testMap.remove(1);
System.out.println("After Remove " + testString);
}
The output is:
Before remove = a
After Remove a
Can anyone explain?

As already mentioned in comments, you are printing stored value of testString again.
If you want to see updated value in testString then you have to assign it
again. like:
HashMap<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(1, "a");
String testString = testMap.get(1);
System.out.println("Before remove = " + testString);
testMap.remove(1);
testString = testMap.get(1);
System.out.println("After Remove " + testString);
Now output will be:
Before remove = a
After Remove null

Removing a element from a collection doesn't change the value of the referenced object.
It changes only the map content :
String content = "test";
testMap.add(1, content);
testMap.remove(1);
System.out.println("After Remove " + testMap.get(1)); // "null" is printed
System.out.println("content"= + content) // content has not changed. So "test" is printed

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

Comparing HashMaps for Matches and Mismatches

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);
}

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.

Array is Returning NULL

My piece of code..
package com.xchanging.selenium.utility;
import java.io.IOException;
import java.util.LinkedHashMap;
import org.apache.commons.lang3.ArrayUtils;
public class DataProviderConvertor extends ReadExcel {
public static Object[][] convertData(String sheetName, String testCaseName)
throws IOException {
LinkedHashMap<String, String> table = ReadExcel.getData(sheetName,
testCaseName);
String[] myStringArray = new String[table.size()];
for (String key : table.values()) {
System.out.println("Keyvalues " + key.toString());
String value = key.toString();
ArrayUtils.add(myStringArray, value);
}
System.out.println("1st Index: " myStringArray[0]);
}
}
It is returning
Keyvalues Y
Keyvalues ie
Keyvalues QC
Keyvalues Yes
Keyvalues Rework Checklist Comments
Keyvalues Yes
Keyvalues MRI Updated Comments
1st Index: null
I am expecting 6 elements in this array but all are returning NULL.. Why it is not returning the expected values..??
How about much simpler way.
public static Object[][] convertData(String sheetName, String testCaseName)
throws IOException {
LinkedHashMap<String, String> table = ReadExcel.getData(sheetName,
testCaseName);
String[] myStringArray = table.values().toArray( new String[ 0 ] );
System.out.println("1st Index: " + myStringArray[0]);
}
Try
for (String key : table.values()) {
System.out.println("Keyvalues " + key.toString());
String value = key.toString();
myStringArray =ArrayUtils.addAll(myStringArray, value);
}
Or
int cnt=0;
for (String key : table.values()) {
System.out.println("Keyvalues " + key.toString());
String value = key.toString();
myStringArray[cnt++] =value;
}
ArrayUtil.add method copies the array and then adds the new element at the end of the new copied array.
So, i think that's where the problem lies in your code.
That is why myStringArray is showing the size as 0.As the myStringArray is copied and a new string array is formed and then the element is added to it.
You can try this -:
int index =0;
for (String key : table.values()) {
System.out.println("Keyvalues " + key.toString());
String value = key.toString();
myStringArray[index++] = value;
}
ArrayUtils.add(myStringArray, value);
This method creates and returns a new array with the value added to it.
You need to assign the result:
myStringArray = ArrayUtils.add(myStringArray, value);
It has to be done that way because arrays cannot be resized.
Just two changes required, code is perfectly fine otherwise.
1.) String[] myStringArray = new String[table.size()];, change to
String[] myStringArray = null;
2.) ArrayUtils.add(myStringArray, value); change to
myStringArray = ArrayUtils.add(myStringArray, value);
Rest you can read and debug about this method in API.

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