Nested Looping to find if Strings equal
Ok, I'm doing a huge project, but I'll cut it down to my current issue.
This project is designed to write a value to an excel sheet using the SmartXLS library.
I need the most efficient way of going through 2 huge arrays and finding if the strings are the same.
I have an Array (dataArr) with 179 Objects with Name Variables (Strings) and an ArrayList (RevNames) with 279 Strings.
With the exception of 1 String in each array, they are in alphabetical order.
When I get the object from dataArr, I get its Name variable. I then go through the RevNames array to see if that name is in the array. If it is in RevNames, I insert the object's appropriate data in the appropriate cell and continue to collect the next object from dataArr. If the name isnt in RevNames, I have to insert the name in alphebatical order in Excel (not RevNames array) by inserting a new row, setting the name, value, ect.
Now, my current code doesnt work, and I need to check the consistancy of my arrays for skipped data, but I know there has to be a more efficent way of doing this. Currently in my code, I have not dealt with the issue of adding new rows to Excel. As is, this nested loop can take 30 seconds to run and I've got to do the same process to 14 other sheets (just get a different variable from object each time).
I also wanted to know if ArrayList's indexOf(Object elem) method would be useful for me here. Is that more efficent than the nested loop?
Code for Nested Loop:
Code :
for(int x=0;x<dataArr.length-1;x++)
{
String tempRName = dataArr[x].Name;
for(int y=0;y<RevNames.size()-1;y++)
{
if(tempRName.equalsIgnoreCase(RevNames.get(y)))
{
workBook2.setNumber(2+y,c,dataArr[y].RevPaxDep);
break;
}
}
}
Re: Nested Looping to find if Strings equal
If all you need is to look for the presence of a String in an array, I'd highly recommend using a Set or Map instead of a List. The lookup is MUCH faster than iterating over an array in a nested loop, and in some implementations (such as TreeSet) the ordering is already implemented. Depending upon how thorough you need your 'search' to be, you could also write your own wrapper class for a String (for example if you need case insensitive you can override the hashCode and equals methods to suit your needs), and this could also contain any extra data necessary
Re: Nested Looping to find if Strings equal
I revised it to this:
Code :
for(int x=0;x<dataArr.length-1;x++)
{
String tempRName = dataArr[x].Name;
int indexAt = RevNames.indexOf(tempRName);
if(indexAt == -1)
System.out.println("--------------Need to Add Row--------------");
else
workBook2.setNumber(2+indexAt,c,dataArr[x].ConnPaxDep);
}
And it runs fine now. Doesnt take nearly as long, but still takes some time. Now I've just got to figure out how to add a new entry to my excel. I figure I can deal with adding the rows on all of the sheets during the first loop since they will have to be added to every sheet anyway.
Re: Nested Looping to find if Strings equal
Quote:
Originally Posted by
aussiemcgr
And it runs fine now. Doesnt take nearly as long, but still takes some time
Its up to you, but once again I encourage you to use a Set or Map. This is their purpose. A short demo:
Code java:
public class Test{
/**
*Analyzes the speed of list versus set searches
*/
public static void main(String[] args){
final int max = 10000;
ArrayList<String> list = new ArrayList<String>(max);
Set<String> set = new HashSet<String>(max);
//First populate the list and set with identical values
for ( int i = 0; i < max; i++ ){
list.add(Integer.toString(i));
set.add(Integer.toString(i));
}
long start = System.currentTimeMillis();
//search the list max number of times
for ( int i = 0; i < max; i++ ){
int num = (int)(Math.random() * max);
list.indexOf(Integer.toString(num));
}
System.out.print("Time to search list: ");
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
//search the set max number of times
for ( int i = 0; i < max; i++ ){
int num = (int)(Math.random() * max);
set.contains(Integer.toString(num));
}
System.out.print("Time to search set: ");
System.out.println(System.currentTimeMillis() - start);
}
}
On my system:
Code :
Time to search list: 531
Time to search set: 0
Just my .02
Re: Nested Looping to find if Strings equal
Quote:
Originally Posted by
copeg
Its up to you, but once again I encourage you to use a Set or Map. This is their purpose. A short demo:
Code java:
public class Test{
/**
*Analyzes the speed of list versus set searches
*/
public static void main(String[] args){
final int max = 10000;
ArrayList<String> list = new ArrayList<String>(max);
Set<String> set = new HashSet<String>(max);
//First populate the list and set with identical values
for ( int i = 0; i < max; i++ ){
list.add(Integer.toString(i));
set.add(Integer.toString(i));
}
long start = System.currentTimeMillis();
//search the list max number of times
for ( int i = 0; i < max; i++ ){
int num = (int)(Math.random() * max);
list.indexOf(Integer.toString(num));
}
System.out.print("Time to search list: ");
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
//search the set max number of times
for ( int i = 0; i < max; i++ ){
int num = (int)(Math.random() * max);
set.contains(Integer.toString(num));
}
System.out.print("Time to search set: ");
System.out.println(System.currentTimeMillis() - start);
}
}
On my system:
Code :
Time to search list: 531
Time to search set: 0
Just my .02
On my crazy slow work computer (takes about 40 seconds to open a new tab in IE and 40 seconds to open the excel sheet I'm working on) it takes me 313 milliseconds to run the code I have now.
I know its not 10000 x 10000 elements, but the miliisecond difference doesnt justify rediting the code for all of 15 sheet entries again.