Compare 2D Arrays in Java and print differences - java

EDIT: closed because it seems that the code below works
I am currently facing the following problem:
I have two two-dimensional arrays, of which the second dimension always has the size 7 (max. index is therefore 6).
Now I need to compare these arrays.
I want to print out if there has been a field added or removed, at any index.
For example:
Array 1:
0|1|2|3
0 |1|2|5
1 |4|4|6
(...)
6 |6|2|8
Array 2
0|1|2|3|4
0 |1|1|2|5
1 |4|4|4|6
(...)
6 |6|7|2|8
As you can see, I have added a column to the second array.
Now I need to print out this column or add it to an array list.
The same has to happen when a column gets removed or changed.
How can I achieve that?
My code so far:
static List<String[]> differences;
static List<String[]> checkForDifferences(String[][] tableOld,String[][] tableNew) {
differences = new ArrayList<String[]>();
if(!Arrays.deepEquals(tableNew,tableOld)) {
for(int hour = 0; hour < tableOld.length;hour++) {
try {
boolean removed = true;
for(int hour2 = 0;hour2 < tableNew.length;hour2++)
if(Arrays.equals(tableOld[hour],tableNew[hour2]))
removed = false;
if(removed)
differences.add(new String[]{"-",tableOld[hour][0], tableOld[hour][1], tableOld[hour][2], tableOld[hour][3], tableOld[hour][4], tableOld[hour][5], tableOld[hour][6]});
} catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
break;
}
}
for (int hour = 0; hour < tableNew.length; hour++) {
try {
boolean added = true;
for (int hour2 = 0; hour2 < tableOld.length; hour2++)
if (Arrays.equals(tableNew[hour], tableOld[hour2]))
added = false;
if (added)
differences.add(new String[]{"+", tableNew[hour][0], tableNew[hour][1], tableNew[hour][2], tableNew[hour][3], tableNew[hour][4], tableNew[hour][5], tableNew[hour][6]});
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
break;
}
}
return differences;
} else {
return null;
}
}

Apparently, my code works. I was just using it wrong.

Related

Sum of numerous String Values Using Loop

enter image description hereI have a String named as Price. I take values of Price from the firebase database. I want to make sum of these String Values and make a total Price. The Value of Price increases automatically according to the child in the database. For example the values are 100, 70, 50, 20, 40 etc. And it will increase accordingly.
I think there should be a loop to make the sum of all these values to make it total price.
This is what i have done so far.
int pos = 0;
JSONObject jsonObject = new JSONObject();
if (jsonObject.has(Integer.toString(pos))) {
} else {
try {
jsonObject.put(Integer.toString(pos),Price);
} catch (JSONException e) {
e.printStackTrace();
}
}
for (int i = 0; i < jsonObj.length(); i++) {
try {
String itemInArray = jsonObj.getString(String.valueOf(i));
int Sum = 0;
int totalPrice = sum + itemInArray;
} catch (JSONException e) {
e.printStackTrace();
}
}
But The code is not working. Please any help would be appreciated.
Let's isolate the part of the code where is the problem of Summing numerous String Values Using Loop.
for (int i = 0; i < jsonObj.length(); i++) {
try {
String itemInArray = jsonObj.getString(String.valueOf(i));
int Sum = 0;
int totalPrice = sum + itemInArray;
} catch (JSONException e) {
e.printStackTrace();
}
}
Every time you loop through this code you reassign the value of 0 to Sum and as a result totalPrices value is always 0 plus the itemInArray (which, another problem, is a String and cannot be directly added to an integer).
Assuming everything else is right and itemInArray holds a numeric value here is the code to find the total price:
try{
int sum = 0; // you don't need the totalPrice variable, they will hold the same result
for (int i=0;i<jsonObj.length(); i++) {
String itemInArray = jsonObj.getString(String.valueOf(i));
int itemPrice = Integer.ParseInt(itemInArray);
sum = sum + itemPrice;
}
}catch (JSONException e) {
e.printStackTrace();
}
Now the sum is not redefined in every loop, it keeps its value from the previous loop and it adds itself and itemPrice in the next iteration.

Unable to write values into excel using multiple workbook.write methods

The below code is working without any runtime error if I call the owb.write(fileOut) and fileOut.close() method only once at at the ending (commented as write and close positioning) but the problem here is that the first value to be set when k=1, is not being printed in the workbook. It works fine when the iteration is in other columns and k=1.Only the first iteration is not being printed. Rest of the values are being set correctly.
I tried using multiple workbook.write() method. If you look at the below code, commented as [1], I had to invoke owb.write(fileOut) separately in the if condition(commented as if condition[1]) and else condition(commented as else condition [2]) because as I said, first value was not getting set in the workbook. I am getting the following runtime error while trying to execute the code in this scenario: Fail to save: an error occurs while saving the package : The part /docProps/app.xml fail to be saved in the stream with marshaller org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller#3740f768
for(int i=0;i<noOfCols1;i++)
{
for(int j=1;j<=noOfRows1;j++)
{
value1 = formatter.formatCellValue(sheet1.getRow(j).getCell(i));
for(int m=1;m<=noOfRows2;m++)
{
value2 = formatter.formatCellValue(sheet2.getRow(m).getCell(i));
value1= value1.trim();
value2=value2.trim();
int value2Position = sheet2.getRow(m).getCell(i).getRowIndex();
if(!positions.contains(value2Position))
{
if(value1.contentEquals(value2))
{
positions.add(value2Position);
matched = true;
}
else{
matched = false;
}
}
if(matched==true)
{
break;
}
}
if(matched == false)
{
int k=1;
if(cFilledPositions.isEmpty()) //If condition[i]
{
rowHead = sheet.createRow((short)k);
rowHead.createCell(i).setCellValue(value1);
owb.write(fileOut); //[1]
}
else //else condition [1]
{
int l = cFilledPositions.size()-1;
k = cFilledPositions.get(l)+1;
rowHead = sheet.createRow((short)k);
rowHead.createCell(i).setCellValue(value1);
owb.write(fileOut);
}
cFilledPositions.add(k);
}
matched = false;
}
cFilledPositions.clear();
positions.clear();
}
//write and close positioning
fileOut.close();
I tried debugging and found that the createRow() method deletes the values previously created if called again on the same row.
To elaborate this, suppose the sheet.createRow() sets the value of a cell in the first iteration, and when it finishes its iteration in the j for loop, the cFilledPositions list is cleared and while it comes back after going to the main loop, 'cFilledPositionswill be empty and the integerkwill again be initialized to1. This is whencreateRow(k)` which is 1 is called again. This would flush out the previously existing values in the 1st row. I am trying to figure out a work around for this and will edit my answer with the solution if I my code works.
Below was the work around. I checked if the row is empty. The createRow function is called only when the row is empty. I have added the comments for the new code.
for(int i=0;i<noOfCols1;i++)
{
for(int j=1;j<=noOfRows1;j++)
{
value1 = formatter.formatCellValue(sheet1.getRow(j).getCell(i));
for(int m=1;m<=noOfRows2;m++)
{
value2 = formatter.formatCellValue(sheet2.getRow(m).getCell(i));
value1= value1.trim();
value2=value2.trim();
int value2Position = sheet2.getRow(m).getCell(i).getRowIndex();
if(!positions.contains(value2Position))
{
if(value1.contentEquals(value2))
{
positions.add(value2Position);
matched = true;
}
else{
matched = false;
}
}
if(matched==true)
{
break;
}
}
if(matched == false)
{
int k=1;
if(cFilledPositions.isEmpty())
{
try{
isEmpty = checkIfRowIsEmpty(sheet,k,formatter);
if(isEmpty)
{
rowHead = sheet.createRow(k);
}
rowHead.createCell(i).setCellValue(value1);
}
catch (Exception e){
try{
rowHead = sheet.createRow(k);
rowHead.createCell(i).setCellValue(value1);
}
catch (Exception e1){
}
}
}
else
{
int l = cFilledPositions.size()-1;
k = cFilledPositions.get(l)+1;
try{
isEmpty = checkIfRowIsEmpty(sheet,k,formatter);
if(isEmpty)
{
rowHead = sheet.createRow(k);
}
rowHead.createCell(i).setCellValue(value1);
}
catch (Exception e)
{
try{
rowHead = sheet.createRow(k);
rowHead.createCell(i).setCellValue(value1);
}
catch (Exception e1){
}
}
}
cFilledPositions.add(k);
}
matched = false;
}
cFilledPositions.clear();
positions.clear();
}

Retrieving Unknown Value using Jsoup

I'm attempting to pull the 'Total Cash Flow From Operating Activities' figure from Yahoo Finance. The variable "s" can be any symbol in the SP500. For the most part, the desired output occurs. However, in some cases, like for AAPL, I can't figure out what it's printing or where it came from.
If "s" is A, the output is 711000000. Correct.
If "s" is AA, the output is 1674000000. Correct.
However, if "s" is AAPL, the output is -416542144. No clue where that comes from.
public class CashFlowStatement {
String cashFromOperatingActivities = "Total Cash Flow From Operating Activities";
public CashFlowStatement(String s) {
String cashFlowStatementURL = ("https://finance.yahoo.com/q/cf?s="+s+"+Cash+Flow&annual");
String cashFlowStatementTableName = "table.yfnc_tabledata1";
boolean foundLine = false;
String line;
int line2;
try {
Document doc = Jsoup.connect(cashFlowStatementURL).get();
for (Element table : doc.select(cashFlowStatementTableName)) {
for (Element row : table.select("tr")) {
if(foundLine == false) {
Elements tds = row.select("td");
for( int j = 0; j < tds.size() - 1; j++) {
if(tds.get(j).text().equals(cashFromOperatingActivities)) {
line = tds.get(j+1).text().replaceAll(",","");
line = line.substring(0,(line.length())-2);
line2 = Integer.parseInt(line)*1000;
System.out.println(line2);
foundLine = true;
}
}
}
}
}
}
catch (IOException ex) {
ex.printStackTrace();
}
catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
}
You have an OVERFLOW! The value from the table is 59,713,000. When you multiply it by 1000 - line2 = Integer.parseInt(line)*1000; you get a number which is greater than MAXINT, thus the negative value. Try use long instead int for line2.

Find ArrayList method to Find Array method

I made a method which finds a value in my ArrayList. I also copied this method so I could use it for my array but certain things such as the get and size don't work. I'm unsure how I'm supposed to restructure it.
public Product findProduct(String givenProduct) throws IllegalProductCodeException {
IllegalProductCodeException notFoundMessage
= new IllegalProductCodeException("Product was not found");
int size = rangeOfProducts.length;
int i = 0;
boolean productFound = false;
while (!productFound && i < size) { //While book hasn't been found and i is less than the size of the array
productFound = rangeOfProducts.get(i).getProductCode().equals(givenProduct);
//Checks whether the given value in the array's reference is equal to the given reference entered
i++; //if not then add 1
}
if (productFound) {
return rangeOfProducts.get(i - 1);
} else {
throw notFoundMessage;
}
}
The array alternative to .get(i) will be [i] and the alternative to .size() will be .length.
for (Product product : products) {
if (product.getProductCode().equals(givenProduct)) {
return product;
}
}
throw new IllegalProductCodeException("Product was not found");
Edit: Java 5's enhanced for loop is equivalent to
for (Iterator<Product> iter=products.iterator(); iter.hasNext(); ) {
Product product = iter.next();

counting unique combinations of object properties

I have a class TypesHolder that has four properties which are each int values. I want to identify how many unique combinations of values are in the four int variables, and then to give a count of how many instances of TypesHolder have each specific combination of the four integer variables. How can I accomplish this in code? My code attempt below is failing, with the failed results summarized at the end. There must be a simpler way to do this correctly.
Here is my TypesHolder class:
public class TypesHolder {
private int with;
private int type;
private int reason1;
private int reason2;
//getters and setters
}
To hold the unique combinations during analysis, I created the following TypesSummaryHolder class:
public class TypesSummaryHolder {
private int with;
private int type;
private int reason1;
private int reason2;
private int count;
//getters and setters
}
I then created an ArrayList to store the 15000+ instances of TypesHolder and another ArrayList to store the TypesSummaryHolder objects who represent each of the unique combinations of width, type, reason1, and reason2 from the TypesHolder objects, along with a count variable for each of the unique combinations. I wrote the following code to populate the ArrayList of TypesSummaryHolder objects along with their counts:
#SuppressWarnings("null")
static void countCommunicationTypes(){
int CommunicationWithNumber;int CommunicationTypeNumber;int CommunicationReasonNumber;
int SecondReasonNumber;int counter = 0;
ArrayList<EncounterTypesHolder> types = new ArrayList<EncounterTypesHolder>();
ArrayList<EncounterTypesSummaryHolder> summaries = new ArrayList<EncounterTypesSummaryHolder>();
////////
try {Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}
catch (ClassNotFoundException e1) {e1.printStackTrace();}
Connection sourceConn = null;
try {sourceConn = DriverManager.getConnection("jdbc:odbc:PIC_NEW_32");}
catch (Exception e1) {e1.printStackTrace();}
Statement st = null;
try {st = sourceConn.createStatement();}
catch (Exception e1) { e1.printStackTrace();}
ResultSet rest = null;
try {
rest = st.executeQuery("SELECT * FROM someTable");
while (rest.next()) {
CommunicationWithNumber = rest.getInt(3);
CommunicationTypeNumber = rest.getInt(5);
CommunicationReasonNumber = rest.getInt(6);
SecondReasonNumber = rest.getInt(6);
EncounterTypesHolder etype = new EncounterTypesHolder();
etype.setWith(CommunicationWithNumber);
etype.setType(CommunicationTypeNumber);
etype.setReason1(CommunicationReasonNumber);
etype.setReason2(SecondReasonNumber);
if(!isDuplicateType(etype,types)){
EncounterTypesSummaryHolder summaryholder = new EncounterTypesSummaryHolder();
summaryholder.setWith(CommunicationWithNumber);
summaryholder.setType(CommunicationTypeNumber);
summaryholder.setReason1(CommunicationReasonNumber);
summaryholder.setReason2(SecondReasonNumber);
summaryholder.setCount(1);
summaries.add(summaryholder);
} else {
EncounterTypesSummaryHolder summaryholder = new EncounterTypesSummaryHolder();
summaryholder.setWith(etype.getWith());
summaryholder.setType(etype.getType());
summaryholder.setReason1(etype.getReason1());
summaryholder.setReason2(etype.getReason2());
if(isDuplicateSummaryType(summaryholder, summaries)){
for(int u = 0; u<summaries.size();u++){
if((CommunicationWithNumber==summaries.get(u).getWith()) && (CommunicationTypeNumber==summaries.get(u).getType()) && (CommunicationReasonNumber==summaries.get(u).getReason1()) && (SecondReasonNumber==summaries.get(u).getReason2()) ){
int oldcount = summaries.get(u).getCount();
int newcount = oldcount+1;
summaries.get(u).setCount(newcount);
}
}
}else {
summaryholder.setCount(1);
summaries.add(summaryholder);
}
}
types.add(etype);
counter += 1;
System.out.println("counter is: "+counter);
System.out.println("summaries.size() is: "+summaries.size());
}
} catch (Exception e) {e.printStackTrace();}
System.out.println("at end: counter is: "+counter);
System.out.println("at end: types.size() is: "+types.size());
System.out.println("at end: summaries.size() is: "+summaries.size());
int total = 0;
for(int r=0;r<summaries.size();r++){
total += summaries.get(r).getCount();
int with = summaries.get(r).getWith();int type = summaries.get(r).getType();int reason1 = summaries.get(r).getReason1();int reason2 = summaries.get(r).getReason2();int thiscount = summaries.get(r).getCount();
}
System.out.println("total is: "+total);
}
static boolean isDuplicateType(EncounterTypesHolder testType, ArrayList<EncounterTypesHolder> types){
for(int j = 0; j<types.size(); j++){
if( (testType.getWith() == types.get(j).getWith()) && (testType.getType() == types.get(j).getType()) && (testType.getReason1() == types.get(j).getReason1()) && (testType.getReason2() == types.get(j).getReason2())){
System.out.println("=====TRUE!!====");
return true;
}
}
return false;
}
static boolean isDuplicateSummaryType(EncounterTypesSummaryHolder testType, ArrayList<EncounterTypesSummaryHolder> types){
for(int j = 0; j<types.size(); j++){
if( (testType.getWith() == types.get(j).getWith()) && (testType.getType() == types.get(j).getType()) && (testType.getReason1() == types.get(j).getReason1()) && (testType.getReason2() == types.get(j).getReason2())){
System.out.println("=====TRUE!!====");
return true;
}
}
return false;
}
The code above is producing the following SYSO output at the end:
at end: counter is: 15415
at end: types.size() is: 15415
at end: summaries.size() is: 15084
total is: 2343089
The max possible value for summaries.size() should be around 600, but the 331 you get from types.size() minus summaries.size() above is within the range of believable values for summaries.size(). However, the value for total should be equal to the 15414 value of types.size(). What is wrong with my code above? How can I change my code above to get both a list of the unique combinations of with, type, reason1, and reason2, and also a count of the number of instances with each of those unique value combinations?
If I understand you right, you could add hashcode() and equals() methods to to TypesHolder, then add all your values to a Set<TypesHolder> of some sort. Then just count the total objects (call size()) in the set to get the number of unique combinations.
Here's a link to implementing hashcode() and equals() from SO, if you're not familiar with those methods. Google is your friend.

Categories

Resources