三个 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 已正确实现 equals
和 hashcode
。
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)
我有一个带有一些 @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 已正确实现 equals
和 hashcode
。
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)