三个 ArrayList 的公共部分

Common part from three ArrayList

我有一个带有一些 @RequestParam(required = false) 的控制器,它必须 return 所有带有一些过滤器的药物(如果存在的话),为这个控制器服务,它包含它的逻辑,但它是不工作。主要问题是我有 3 个 ArrayList,我无法想出如何找到所有三个 ArrayList 中存在的所有元素:)

    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();
}

从多个列表中获取所有公共元素的一个选项是迭代第一个列表并过滤掉所有其他列表中存在的所有元素,因此:

List<Medicine> resultList = lessList.stream()
        .filter(moreList::contains)
        .filter(namesList::contains)
        .collect(Collectors.toList());

虽然这可行,但如果列表较大,您可以考虑使用 HashSets 而不是列表,以获得更好的性能。

此外,此代码假定 Medicine class 已正确实现 equalshashcode

Collection#retainAll() 方法只会保留出现在另一个 Collection 中的项目;换句话说,两个集合的交集。使用两次得到三个集合的交集:

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]

最好的方法是使用 retainAll 方法从列表中删除所有不常见的项目。 https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#retainAll(java.util.Collection)