java object creation - java

public class ServersList {
private Host host;
private Server server;
private InfoList infoList;
private List<AbcInformation> abcInformation;
#XmlElement(name = "Host")
#JsonProperty("Host")
public Host getHost() {
return this.host;
}
//Get Set functions for all object
}
We have the above class. It contains some object of other classes and get/set methods as shown above. We are parsing an XML file and creating an array of ServersList class. For example,
ServersList[] serversArray = new ServersList[count];
for (int index = 0; index < count; index++) {
serversArray[index] = new ServersList();
serversArray[index].setInfoList(serConfig
.getInfoList());
serversArray[index].setHost(serConfig
.getHost());
serversArray[index].setServer(serConfig
.getServer());
serversArray[index].getHost().setCid(
listResponse.getHost().get(index).getCid());
serversArray[index].getHost().setCName(
listResponse.getHost().get(index).getCname());
serversArray[index].getHost()
.setCurrentName(listResponse.getHost().get(index)
.getCurrentName());
serversArray[index].getHost().setHostName(listResponse.getHost().
get(index).getName());
serversArray[index].getHost().setHostUuid(
listResponse.getHost().get(index).getId());
}
Our problem is after the for loop all values of the serversArray array will be same (may be with last element in the xml). While debugging I understand that, every iteration the value of every rows are changed the values of current row. Can you suggest a solution for this?

Try doing this, should work.
public static void main(String[] args) {
ServersList sList=null;
int count=10;
ServersList[] serversArray = new ServersList[count];
for (int index = 0; index < count; index++) {
sList = new ServersList();
sList.setHost(....);
//..........other setter...........
serversArray[index] = sList;
}
for (ServersList serversList : serversArray) {
System.out.println(serversList.getHost());
}
}

Finally I found the solution. I have added copy constructors for the following classes
ServersList, Host, Server, InfoList, AbcInformation

Related

TestNG data provider convert object 2d array to Hashtable - throws MethodMatcherException

I have Data provider defined to get the data from excel sheet and passing it to the test method of testing. I am able to get and read data from excel but when passing it to the testing method under test it throws MethodMatcherException
Code from dataProvider
#DataProvider(name = "testdatasupply")
public Object[][] ReadDetails() throws IOException {
HashMap<String,String> rowdata=new HashMap<String,String>();
File file=new File("src/main/resources/TestData.xlsx");
FileInputStream fis=new FileInputStream(file);
XSSFWorkbook wb= new XSSFWorkbook(fis);
XSSFSheet sheet=wb.getSheet("API");
Row key=sheet.getRow(0);
int rowcount=sheet.getPhysicalNumberOfRows();
int columncount=key.getLastCellNum();
Object[][] data1 =new Object[rowcount][columncount];
for(int i=0;i<sheet.getPhysicalNumberOfRows()-1;i++) {
Row row = sheet.getRow(i+1);
if(row.getCell(2).getStringCellValue().equalsIgnoreCase("Yes")){
for (int j = 0; j < row.getLastCellNum(); j++) {
rowdata.put(key.getCell(j).getStringCellValue(), row.getCell(j).getStringCellValue());
}
data1[i][0]=rowdata;
System.out.println(data1[i][0]);
}
}
return data1;
}
And my testing class under test .
#Test(dataProvider = "testdatasupply",dataProviderClass = TestData.ReadData.class)
public void APITesting(Hashtable<String,String> data){
System.out.println(data);
String API= data.get("API Name");
switch (API.toLowerCase()){
case "petstore/get":
System.out.println(data.get("ID"));
case "petstore/post":
System.out.println(data.get("ID")+"from secnd");
}
}
When I run above code, I am getting org.testng.internal.reflect.MethodMatcherException: which shows return type is not matching as expected. Since I have more columns , getting it as individual string is not helping as I have to create more number of variables.
[public void TestRunner.main.testrunner.APITesting(java.util.Hashtable)] has no parameters defined but was found to be using a data provider (either explicitly specified or inherited from class level annotation).
Data provider mismatch
Method: APITesting([Parameter{index=0, type=java.util.Hashtable, declaredAnnotations=[]}])
Can anyone suggest best way to get this as Hashtable or what I am doing wrong here?
Your dataprovider returns a HashMap for each test, while your test method expects a parameter of type Hashtable. These two are different data types. But both have a common interface Map.
So, in your test method, change as below:
public void APITesting(Map<String,String> data)
In your data provider change as: (not required, but recommended):
Map<String,String> rowdata=new HashMap<String,String>();
Also, your code dataprovider code has some issues - The same map, rowdata is being used inside the loop, So for every test run the data passed to the test method would be the same since you are doing data1[i][0]=rowdata; within the i loop.
I assume you should be doing:
for(int i=0;i<sheet.getPhysicalNumberOfRows()-1;i++) {
Row row = sheet.getRow(i+1);
// initialize the map here.
Map<String,String> rowdata=new HashMap<String,String>();
if(row.getCell(2).getStringCellValue().equalsIgnoreCase("Yes")){
for (int j = 0; j < row.getLastCellNum(); j++) {
rowdata.put(key.getCell(j).getStringCellValue(), row.getCell(j).getStringCellValue());
}
data1[i][0]=rowdata;
System.out.println(data1[i][0]);
}
}
Your code seems incorrect and you can do the following things:
1). First Solution:
a) #Test method cannot have public void APITesting(Hashtable<String,String> data) try to replace it with public void APITesting(String API, String ID)
b) In the data provider try to return the ID and API. You need to parse data before returning it. In the dataprovider method you need to get the API and ID and then pass it to the #test method.
data1[i][0]=APIData;
data1[i][1]=ID;
Code:
#Test(dataProvider = "testdatasupply",dataProviderClass = TestData.ReadData.class)
public void APITesting(String API, String ID) {
switch (API.toLowerCase()) {
case "petstore/get":
System.out.println(ID);
case "petstore/post":
System.out.println(ID + "from secnd");
}
}
2) Second Solution:
As you cannot pass the public void APITesting(Hashtable<String,String> data) try to again replace it with public void APITesting(String data) and then convert the string to hashtable again.
Code:
#Test(dataProvider = "testdatasupply",dataProviderClass = TestData.ReadData.class)
public void APITesting(String data) {
String a = data.toString();
a = a.replaceAll("[{}]","");
System.out.println(a);
// New HashTable obj
Hashtable<String, String> hashTable
= new Hashtable<String, String>();
// split the String by a comma
String parts[] = a.split(",");
// iterate the parts and add them to a HashTable
for (String part : parts) {
String subData[] = part.split("=");
String api = subData[0].trim();
String id = subData[1].trim();
// Add to hashTable
hashTable.put(api, id);
}
System.out.println("String to HashTable: " + hashTable);
System.out.println(hashTable.get("API"));
System.out.println(hashTable.get("id"));
String API= hashTable.get("API Name");
switch (API.toLowerCase()){
case "petstore/get":
System.out.println(hashTable.get("ID"));
case "petstore/post":
System.out.println(hashTable.get("ID")+"from secnd");
}
}

Array becoming empty after getting out of a for loop

I'm learning to program in Java for Android Studio. I'm working with a Parse.com query downloading information. I store the information inside an array of a costume object called MyData. When I'm storing the information I can log the content of the array and it has the correct info. But latter when I try to use the same array, if I use the .length function it says it's null. And if I try to retrieve any of the information, it's empty.
This I my object:
public class MyData {
Integer gluc;
Integer insulinaV;
Date fec;
Integer alimento;
String comentarios;
public MyData(Integer gluc, Integer insulinaV, Date fec, Integer alimento, String comentarios) {
this.gluc = gluc;
this.insulinaV = insulinaV;
this.fec = fec;
this.alimento = alimento;
this.comentarios = comentarios;
}
public Integer getGluc() {
return gluc;
}
public Integer getInsulinaV() {
return insulinaV;
}
public Date getFec() {
return fec;
}
public Integer getAlimento() {
return alimento;
}
public String getComentarios() {
return comentarios;
}
}
So, to retrieve the information I use array[I].getWhatever(), this is how I store the information:
public void downloadInformation() {
user = ParseUser.getCurrentUser();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Glucosa");
query.whereEqualTo("usuario", user);
query.orderByDescending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null && objects.size() > 0) {
Log.d("score!", "Objects Retrived");
Log.d("size", String.valueOf(objects.size()));
int i = 0;
indexsize = 0;
for (ParseObject object : objects) {
dataArray = new MyData[objects.size()];
dataArray[i] = new MyData(object.getInt("glucosa"), object.getInt("insulina"), object.getDate("fecha"), object.getInt("Alimentos"), object.getString("Comentarios"));
String alimentosexiste = dataArray[i].getAlimento().toString();
Log.i("Is Empty or Not=", alimentosexiste);
indexsize = indexsize+1;
i++;
}
} else {
Log.d("failed", "error");
}
}
});
}
In my logcat I'm getting "Score! Objects retrieved" and "Size: 22", also I get a list with all 22 elements of the "Is Empty or Not" Log. So far so good.
Then, In my attempt to move from this activity to another, I try to save the dataArray with:
public void saveInformation() {
int j = indexsize;
Log.i("size of index?", String.valueOf(indexsize));
for (int i=0; i<=j; i++) {
Log.i("index", String.valueOf(i));
alimentosVal = dataArray[i].getAlimento();
comentariosVal = dataArray[i].getComentarios();
glucVal = dataArray[i].getGluc();
insulinaVal = dataArray[i].getInsulinaV();
fecVal = dataArray[i].getFec();
}
SQLiteDatabase myGlucosebase = this.openOrCreateDatabase("GlucoseEvents", MODE_PRIVATE, null);
myGlucosebase.execSQL("CREATE TABLE IF NOT EXISTS glucoseevents (alimentos INT(2), comentarios VARCHAR, gluc INT(4), insulinv INT(4), fec DATETIME)");
myGlucosebase.execSQL("INSERT INTO glucoseevents (alimentos, comentarios, gluc, insulinv, fec) VALUES (alimentosVal, comentariosVal, glucVal, insulinaVal, fecVal) ");
}
And even do I printed before the content of the array with index [0] (so I'm sure the information got stored in the array), I get the following error:
Attempt to invoke virtual method 'java.lang.Integer com.parse.starter.MyData.getAlimento()' on a null object reference
I've seen that the problem is that I'm pointing to an empty element, but it was working before, how can I do this?
(Data array is declared at the beginning, below the class name as: MyData[] dataArray;)
Thanks!
dataArray = new MyData[objects.size()]; should be outside the for loop
Your class MyData does not have a "dataArray". At least not in the example code you give above.

String cannot be added to List using Object in Java

I am working on a JSF based Web Application where I read contents from a file(dumpfile) and then parse it using a logic and keep adding it to a list using an object and also set a string using the object. But I keep getting this error. I am confused where I am wrong. I am a beginner so can anyone be kind enough to help me?
List<DumpController> FinalDumpNotes;
public List<DumpController> initializeDumpNotes()
throws SocketException, IOException {
PostProcessedDump postProcessedDump = (PostProcessedDump) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("postProcessedDump");
List<DumpController> FinalNotes = new ArrayList<>();
if (postProcessedDump.getDumpNotes() == null) {
dumpNotes = new DumpNotes();
}
DumpListController dlcon = (DumpListController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("dumpListController");
DumpInfo dumpinfo = dlcon.getSelectedDumpInfo();
String fileName = dumpinfo.getDate() + dumpinfo.getTime() + dumpinfo.getSeqNo() + dumpinfo.getType() + dumpinfo.getTape() + dumpinfo.getDescription() + ".txt";
if (checkFileExistsInWin(fileName)) {
postProcessedDump.setDumpnotescontent(getFileContentsFromWin(fileName));
String consolidateDumpnotes = getFileContentsFromWin(fileName);
String lines[];
String content = "";
lines = consolidateDumpnotes.split("\\r?\\n");
List<String> finallines = new ArrayList<>();
int k = 0;
for (int i = 0; i < lines.length; i++) {
if (!lines[i].equalsIgnoreCase("")) {
finallines.add(lines[i]);
k++;
}
}
for (int j = 0; j < finallines.size(); j++) {
if (finallines.get(j).startsWith("---------------------SAVED BY")) {
PostProcessedDump dump = new PostProcessedDump();
dump.setDumpMessage(content);
content = "";
FinalDumpNotes.add(dump);
} else {
content = content + finallines.get(j);
}
}
}
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("postProcessedDump", postProcessedDump);
return FinalDumpNotes;
}
I get the following error:
If you want to add instances of type PostProcessedDump to your List you should change it's type. Also, don't forget to initialize it. Something like,
List<PostProcessedDump> FinalDumpNotes = new ArrayList<>();
Also, Java naming convention is to start variable names with a lower case letter. FinalDumpNotes looks like a class, I would suggest something like
List<PostProcessedDump> processedList = new ArrayList<>();
Problems with your code:
List<DumpController> FinalDumpNotes;
You declare FinalDumpNotes to be a List of DumpController objects, but you never initialize it. In addition, your IDE is barfing on the following line of code:
FinalDumpNotes.add(dump);
because you are attempting to add a PostProcessedDump object to the List instead of a DumpController object.
For starters, you need to initialize your list like this:
List<DumpController> finalDumpNotes = new ArrayList<DumpController>();
Notice that I have made the variable name beginning with lower case, which is the convention (upper case is normally reserved for classes and interfaces).
I will leave it to you as a homework assignment to sort out the correct usage of this List.

Java sanitizing Arraylist records suggestions

I am looking for an idea how to accomplish this task. So I'll start with how my program is working.
My program reads a CSV file. They are key value pairs separated by a comma.
L1234456,ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
L6789101,zgna-3mcb-iiiv-pppp-a8yr-c3d2-ct7v-gggg-zz33-33ie
etc
Function takes a file and parses it into an arrayList of String[]. The function returns the ArrayList.
public ArrayList<String[]> parseFile(File csvFile) {
Scanner scan = null;
try {
scan = new Scanner(csvFile);
} catch (FileNotFoundException e) {
}
ArrayList<String[]> records = new ArrayList<String[]>();
String[] record = new String[2];
while (scan.hasNext()) {
record = scan.nextLine().trim().split(",");
records.add(record);
}
return records;
}
Here is the code, where I am calling parse file and passing in the CSVFile.
ArrayList<String[]> Records = parseFile(csvFile);
I then created another ArrayList for files that aren't parsed.
ArrayList<String> NotParsed = new ArrayList<String>();
So the program then continues to sanitize the key value pairs separated by a comma. So we first start with the first key in the record. E.g L1234456. If the record could not be sanitized it then it replaces the current key with "CouldNOtBeParsed" text.
for (int i = 0; i < Records.size(); i++) {
if(!validateRecord(Records.get(i)[0].toString())) {
Logging.info("Records could not be parsed " + Records.get(i)[0]);
NotParsed.add(srpRecords.get(i)[0].toString());
Records.get(i)[0] = "CouldNotBeParsed";
} else {
Logging.info(Records.get(i)[0] + " has been sanitized");
}
}
Next we do the 2nd key in the key value pair e.g ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
for (int i = 0; i < Records.size(); i++) {
if(!validateRecordKey(Records.get(i)[1].toString())) {
Logging.info("Record Key could not be parsed " + Records.get(i)[0]);
NotParsed.add(Records.get(i)[1].toString());
Records.get(i)[1] = "CouldNotBeParsed";
} else {
Logging.info(Records.get(i)[1] + " has been sanitized");
}
}
The problem is that I need both keyvalue pairs to be sanitized, make a separate list of the keyValue pairs that could not be sanitized and a list of the ones there were sanitized so they can be inserted into a database. The ones that cannot will be printed out to the user.
I thought about looping thought the records and removing the records with the "CouldNotBeParsed" text so that would just leave the ones that could be parsed. I also tried removing the records from the during the for loop Records.remove((i)); However that messes up the For loop because if the first record could not be sanitized, then it's removed, the on the next iteration of the loop it's skipped because record 2 is now record 1. That's why i went with adding the text.
Atually I need two lists, one for the Records that were sanitized and another that wasn't.
So I was thinking there must be a better way to do this. Or a better method of sanitizing both keyValue pairs at the same time or something of that nature. Suggestions?
Start by changing the data structure: rather than using a list of two-element String[] arrays, define a class for your key-value pairs:
class KeyValuePair {
private final String key;
private final String value;
public KeyValuePair(String k, String v) { key = k; value = v; }
public String getKey() { return key; }
public String getValue() { return value; }
}
Note that the class is immutable.
Now make an object with three lists of KeyValuePair objects:
class ParseResult {
private final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
private final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
private final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
public ParseResult(List<KeyValuePair> s, List<KeyValuePair> bk, List<KeyValuePair> bv) {
sanitized = s;
badKey = bk;
badValue = bv;
}
public List<KeyValuePair> getSanitized() { return sanitized; }
public List<KeyValuePair> getBadKey() { return badKey; }
public List<KeyValuePair> getBadValue() { return badValue; }
}
Finally, populate these three lists in a single loop that reads from the file:
public static ParseResult parseFile(File csvFile) {
Scanner scan = null;
try {
scan = new Scanner(csvFile);
} catch (FileNotFoundException e) {
???
// Do something about this exception.
// Consider not catching it here, letting the caller deal with it.
}
final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
while (scan.hasNext()) {
String[] tokens = scan.nextLine().trim().split(",");
if (tokens.length != 2) {
???
// Do something about this - either throw an exception,
// or log a message and continue.
}
KeyValuePair kvp = new KeyValuePair(tokens[0], tokens[1]);
// Do the validation on the spot
if (!validateRecordKey(kvp.getKey())) {
badKey.add(kvp);
} else if (!validateRecord(kvp.getValue())) {
badValue.add(kvp);
} else {
sanitized.add(kvp);
}
}
return new ParseResult(sanitized, badKey, badValue);
}
Now you have a single function that produces a single result with all your records cleanly separated into three buckets - i.e. sanitized records, records with bad keys, and record with good keys but bad values.

Getting nullpointerexception while using constructor

public class Author {
private int id;
private String name;
private String university;
private String department;
private String email;
private int article1;
private int article2;
private int article3;
private int article4;
private int article5;
//constructors and getter/setters are generated automatically, not adding to have space
}
This is my Author class. This class only has these attributes. Also I have a readDaFile class which is created to read author.txt and and create author objects.
import java.util.Scanner;
import java.io.*;
public class readAuthor {
private Scanner reader;
private String temp;
private String[] split;
public Author[] authorList;
private int dummyInt,dummyArticle1=0 ,dummyArticle2=0 ,dummyArticle3=0,dummyArticle4,dummyArticle5;
private int i=0;
private String name , university , department , email ;
public void tryOpeningOrDieTrying(){
try{
reader = new Scanner(new File("Author.txt"));
}
catch(Exception exo){
System.out.println("Can not find file.");
}
}
public void readDaFile(){
while(reader.hasNext()){
temp = reader.nextLine();
split = temp.split(" ");
name = "NOTGIVEN";
university = "NOTGIVEN";
department = "NOTGIVEN";
email = "NOTGIVEN";
dummyInt = 0;
dummyArticle1 = 0;
dummyArticle2 = 0;
dummyArticle3 = 0;
dummyArticle4 = 0;
dummyArticle5 = 0;
dummyInt = Integer.parseInt(split[1]);
if(split.length>2){ name = split[2]; }
if(split.length>3){ university = split[3]; }
if(split.length>4){ department = split[4]; }
if(split.length>5){ email = split[5]; }
if(split.length>6){ dummyArticle1 = Integer.parseInt(split[6]); }
if(split.length>7){ dummyArticle2 = Integer.parseInt(split[7]); }
if(split.length>8){ dummyArticle3 = Integer.parseInt(split[8]); }
if(split.length>9){ dummyArticle4 = Integer.parseInt(split[9]); }
if(split.length>10){ dummyArticle5 = Integer.parseInt(split[10]); }
System.out.println(dummyInt+name+university+department+email+dummyArticle1+dummyArticle2+dummyArticle3+dummyArticle4+dummyArticle5);
//authorList[i] = new Author(dummyInt,name,university,department,email,dummyArticle1,dummyArticle2,dummyArticle3,dummyArticle4,dummyArticle5);
i++;
//System.out.println(split[1]);
//System.out.println(split.length);
}
}
public void sealDaGates(){
reader.close();
}
}
Simply I'm reading lines first then split them into sub-elements to create author objects. But Author.txt might not give all author attributes.
For example :
AUTHOR 100
AUTHOR 101 Ruonan_Li MIT Computer_Science ruonan#mit.edu 1002001 1002009 1002004
To prevent sending null parameters to author constructor,I am initializing every attribute variable for every loop. I also checked initialized attribute variables by printf-ing them. They seem to work as intended. If I can't successfully read an attribute from txt , program sends NOTGIVEN or 0 to constructor. But still I am having nullpointerexception at line :
authorList[i] = new Author(dummyInt,name,university,department,email,dummyArticle1,dummyArticle2,dummyArticle3,dummyArticle4,dummyArticle5);
Thanks in advance
You're never initializing authorList, so that's null. It's not the constructor call which is failing - it's the assignment into the array. You need:
authorList = new Author[...];
somewhere. Alternatively - and almost certainly preferrably - use a List<Author>, e.g.
private final List<Author> authorList = new ArrayList<Author>();
Looks like you forgot to initialize the authorList array. In the constructor, add this line authorList = new Author[100]; and that should fix it. Change 100 to whatever number of elements you desire.

Categories