I have a controller with some @RequestParam(required = false) which have to return all medicines with some filters if they are exist, service for this controller, which contains logic for it, but it is not working. The main problem is that I have 3 ArrayList and I cannot come up with how to find all elements which exist in all three ArrayLists :)
public List<Medicine> readAllMedicine(Double lessThenPrice, Double moreThenPrice, String name) {
//when lessThenPrice < moreThenPrice, result of their queries will not have general elements
if ((lessThenPrice != null && moreThenPrice != 0) && lessThenPrice < moreThenPrice) {
return Collections.emptyList();
}
List<Medicine> resultList = new ArrayList<>();
List<Medicine> lessList = new ArrayList<>();
List<Medicine> moreList = new ArrayList<>();
List<Medicine> nameList = new ArrayList<>();
//checking if there are arguments from the controller
if (lessThenPrice != null) {
lessList.addAll(medicineDao.findMedicinesByPriceIsLessThan(lessThenPrice));
}
if (moreThenPrice != null) {
moreList.addAll(medicineDao.findMedicinesByPriceIsGreaterThan(moreThenPrice));
}
if (name != null) {
nameList.addAll(medicineDao.findMedicinesByName(name));
}
//saving general elements
//this part is not working
if (!lessList.isEmpty() || !moreList.isEmpty() || !nameList.isEmpty()) {
List<Medicine> temp = new ArrayList<>(); //it will contain general part of lessList and moreList
for (Medicine medicine : lessList) {
if (moreList.contains(medicine)) {
temp.add(medicine);
}
}
for (Medicine medicine : nameList) {
if (temp.contains(medicine)) {
resultList.add(medicine);
}
}
return resultList;
}
//if there is no args, just return all medicines
return medicineDao.findAll();
}
The Collection#retainAll() method will only keep items that appear in another Collection; in other words, the intersection of two collections. Use it twice to get the intersection of three collections:
List<String> list1 = List.of("a", "b", "c", "q");
List<String> list2 = List.of("b", "d", "e", "q");
List<String> list3 = List.of("b", "q", "r", "s");
List<String> intersection = new ArrayList<String>(list1);
intersection.retainAll(list2);
intersection.retainAll(list3);
System.out.println(intersection); // [b, q]
One option to get all the common elements from multiple lists would be to iterate on the first list and filter out all the elements which exist in every other list, so:
List<Medicine> resultList = lessList.stream()
.filter(moreList::contains)
.filter(namesList::contains)
.collect(Collectors.toList());
While this works, in case of bigger lists, you may consider using HashSets instead of lists, for better performance.
Also, this code assumes Medicine class has proper implementation for equals and hashcode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With