The ConcurrentModificationException originates because the schoolList list is being modified within the process of iterating through that list. An alternative would be iterate the schools list instead and make the additions to the schoolList, which separates the list being iterated from the one being modified:
schoolList = new ArrayList<>();
for (School school: schools) {
String name = school.getName();
String address = vehicle.getAddress();
if (name.contains(searchFilterText)|| address.contains(searchFilterText)) {
schoolList.add(school);
}
}
Another alternative (using JDK 8 or above) is to filter the schools list and capture the result into schoolList:
schoolList = schools.stream()
.filter(school -> school.getName().contains(searchFilterText) || school.getAddress().contains(searchFilterText))
.collect(Collectors.toList());
Based on the current state of the code, it appears that you will be re-adding elements to the schoolList, because it already contains those elements, hence why you are iterating over them. The code examples above result in lists that only contain the matching elements. If it desired to have the matching elements re-added to the schoolList, as in the original question, you can replace the following line in the first example
schoolList = new ArrayList<>();
with
schoolList = new ArrayList<>(school);
This will create a copy of the school list and store it in schoolList before the iteration begins.
Be careful if this is the intended behavior, as it may cause an infinite loop. For example, in the original question, had a ConcurrentModificationException not been thrown, if you add a School object that matches the condition (name.contains(searchFilterText)|| address.contains(searchFilterText)), it will also be iterated later on, which in turn would match the condition, and be re-added. This process would repeat infinitely. For example, suppose the only element in the schoolList matches the condition, the following would be the results contained in schoolList after each iteration:
Iteration 0:
matching school A <-- Current element of iteration
matching school A <-- [newly added element]
Iteration 1:
matching school A
matching school A <-- Current element of iteration
matching school A <-- [newly added element]
Iteration 2:
matching school A
matching school A
matching school A <-- Current element of iteration
matching school A <-- [newly added element]
And so on, infinitely.