简体   繁体   中英

Why iterating list gives me stackoverflow error?

I am getting Stackoverflow whenever below code is ran. I am not able to understand why this is happening? And how we can fix it?

  public boolean compare(List<Task> source, List<Task> actual) {
    return compareTasks(source, actual) && compare(actual, source);
  }

  public boolean compareTasks(List<Task> source, List<Task> actual) {
    matchList = new ArrayList<Task>();
    differList = new ArrayList<Task>();
    for (Task task : actual) {
      if (source.contains(task)) {
        matchList.add(task);
      } else {
        differList.add(task);
      }
    }
    return (differList.size() == 0) ? true : false;
  }

Below is the error:

java.lang.StackOverflowError
    at java.lang.StringBuilder.append(StringBuilder.java:119)
    at com.user.test.Task.getKey(Task.java:209)
    at com.user.test.Task.equals(Task.java:220)
    at java.util.ArrayList.indexOf(ArrayList.java:216)
    at java.util.ArrayList.contains(ArrayList.java:199)
    at java.util.Collections$UnmodifiableCollection.contains(Collections.java:1000)

I believe the issue is in here:

public boolean compare(List<Task> source, List<Task> actual) {
   return compareTasks(source, actual) && compare(actual, source);
}

Imagine you want to compare list A to list B. If you'll notice:

  • Calling compare(A, B) calls compare(B, A).
  • Calling compare(B, A) calls compare(A, B).
  • Calling compare(A, B) calls compare(B, A).
  • Calling compare(B, A) calls compare(A, B).
  • Calling compare(A, B) calls compare(B, A).
  • Calling compare(B, A) calls compare(A, B).
  • Calling compare(A, B) calls compare(B, A).
  • Calling compare(B, A) calls compare(A, B).
  • etc.

This recursion never terminates, so it eventually triggers a stack overflow.

To fix this issue, consider rewriting this as

public boolean compare(List<Task> source, List<Task> actual) {
   return compareTasks(source, actual) && compareTasks(actual, source); // call compareTasks, not compare.
}

You are calling compareTasks again in the method. Change it to the following line: return compareTasksList(source, actual) && compareTasksList(actual, source);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM