Reputation: 15
I'm trying to write a method that takes 2 ArrayLists of doubles and returns all the values in set1 that aren't found in set2. These numbers should be returned in set3. I keep getting an out of memory error. Can anyone point me in the right direction?
ArrayList<Double> setDiff(ArrayList<Double> set1, ArrayList<Double> set2){
ArrayList<Double> set3 = new ArrayList<Double>();
int count = 0;
while(count < set1.size()){
boolean inList = false;
while(inList == false){
int count2 = 0;
while(count2 < set2.size() && set1.get(count) == set2.get(count2)){
count2++;
}
if(count2 != set2.size()){
set3.add(set1.get(count));
}
else{
inList = true;
count++;
}
}
}
return set3;
}
Upvotes: 1
Views: 217
Reputation: 891
Some loop is likely not stopping as you would expect.
The following code snippet would accomplish pretty much the same you are trying to do.
for (Double d : set1) {
if (!set2.contains(d)) {
set3.add(d);
}
}
UPDATE: since you say you cannot use contains(), you can perform the checks by yourself:
for (Double d : set1) {
boolean found = false;
for (int i=0; i<set2.size() && !found; i++) {
if (d.equals(set2.get(i))) {
found = true;
}
}
if (!found) {
set3.add(d);
}
}
EDIT: Furthermore, the problem in your code lies in the line
if(count2 != set2.size()){
You should change != with >, since in the case of being count2 less than set2, the external count variable will not increase, resulting in an infinite loop, and after a few seconds, an OutOfMemoryError.
Also, your algorithm wasn't 100% correct either, since the looping through the second list was not consistent. You can see a similar approach with while-loops below:
int count = 0;
while (count < set1.size()) {
boolean inList = false;
int count2 = 0;
while (inList == false && count2 < set2.size()) {
if (set1.get(count).equals(set2.get(count2))) {
inList = true;
}
count2++;
}
if (!inList) {
set3.add(set1.get(count));
}
count++;
}
Upvotes: 2
Reputation: 3322
it may be advantageous to sort your lists before doing these comaprisons, then searching for items can be performed much more efficiently.
you can also try doing this:
set1.removeAll(set2)
items remaining in set1 were the items not in set2
Upvotes: 2
Reputation: 24336
I would recommend using Collection utils Disjunction
Returns a Collection containing the exclusive disjunction (symmetric difference) of the given Collections.
The cardinality of each element e in the returned Collection will be equal to max(cardinality(e,a),cardinality(e,b)) - min(cardinality(e,a),cardinality(e,b)).
This is equivalent to subtract(union(a,b),intersection(a,b)) or union(subtract(a,b),subtract(b,a)).
Upvotes: 2