Array is Returning NULL - java

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.

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

Removing hashmap key but getting value in previously saved reference

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

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.

Is there a convenient way to convert comma separated string to hashmap

String format is (not json format):
a="0PN5J17HBGZHT7JJ3X82", b="frJIUN8DYpKDtOLCwo/yzg="
I want convert this string to a HashMap:
key a with value 0PN5J17HBGZHT7JJ3X82
key b with value frJIUN8DYpKDtOLCwo/yzg=
Is there a convenient way? Thanks
What I've tried:
Map<String, String> map = new HashMap<String, String>();
String s = "a=\"00PN5J17HBGZHT7JJ3X82\",b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
String []tmp = StringUtils.split(s,',');
for (String v : tmp) {
String[] t = StringUtils.split(v,'=');
map.put(t[0], t[1]);
}
I get this result:
key a with value "0PN5J17HBGZHT7JJ3X82"
key b with value "frJIUN8DYpKDtOLCwo/yzg
for key a, the start and end double quotation marks(") is unwanted; for key b, the start double quotation marks(") is unwanted and the last equals sign(=) is missing.
Sorry for my poor english.
Probably you don't care that it's a HashMap, just a Map, so this will do it, since Properties implements Map:
import java.io.StringReader;
import java.util.*;
public class Strings {
public static void main(String[] args) throws Exception {
String input = "a=\"0PN5J17HBGZHT7JJ3X82\", b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
String propertiesFormat = input.replaceAll(",", "\n");
Properties properties = new Properties();
properties.load(new StringReader(propertiesFormat));
System.out.println(properties);
}
}
Output:
{b="frJIUN8DYpKDtOLCwo/yzg=", a="0PN5J17HBGZHT7JJ3X82"}
If you absolutely need a HashMap, you can construct one with the Properties object as input: new HashMap(properties).
Added few changes in Ryan's code
public static void main(String[] args) throws Exception {
String input = "a=\"0PN5J17HBGZHT7JJ3X82\", b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
input=input.replaceAll("\"", "");
String propertiesFormat = input.replaceAll(",", "\n");
Properties properties = new Properties();
properties.load(new StringReader(propertiesFormat));
Set<Entry<Object, Object>> entrySet = properties.entrySet();
HashMap<String,String > map = new HashMap<String, String>();
for (Iterator<Entry<Object, Object>> it = entrySet.iterator(); it.hasNext();) {
Entry<Object,Object> entry = it.next();
map.put((String)entry.getKey(), (String)entry.getValue());
}
System.out.println(map);
}
Split the String on the Basis of commas (",") and then with with ("=")
String s = "Comma Separated String";
HashMap<String, String> map = new HashMap<String, String>();
String[] arr = s.split(",");
String[] arStr = arr.split("=");
map.put(arr[0], arr[1]);
You can also use the regex as below.
Map<String,String> data = new HashMap<String,String>();
Pattern p = Pattern.compile("[\\{\\}\\=\\, ]++");
String[] split = p.split(text);
for ( int i=0; i+2 <= split.length; i+=2 ){
data.put( split[i], split[i+1] );
}
return data;

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