簡體   English   中英

如何檢查 Java 中不同對象的兩個數組列表中的缺失元素?

[英]How to check for missing elements in two array lists of different objects, in Java?

我有兩個具有不同屬性的類,只有一個具有共同的屬性。 我想比較兩者並提取一個缺少元素的列表。 因此,例如,我們有以下類,其中 inventoryId 和 id 相同,如果葯物列表中缺少它們,這些是我們將要查找的元素。

public class DrugInventory {
    String inventoryId;
    String drugStatus;
}

public class Drug{
    String id;
    String name;
    String quantity;
}

DrugInventory中的inventoryID等於Drug中的id 因此,如果葯物列表中缺少這兩個值,我將查看它們。

List<DrugInventory> drugInventories = new ArrayList<>();

DrugInventory drugInventory = new DrugInventory("121212");
DrugInventory drugInventory1 = new DrugInventory("232323");
DrugInventory drugInventory2 = new DrugInventory("343434");
DrugInventory drugInventory3 = new DrugInventory("454545");
DrugInventory drugInventory4 = new DrugInventory("565656");

drugInventories.add(drugInventory);
drugInventories.add(drugInventory1);
drugInventories.add(drugInventory2);
drugInventories.add(drugInventory3);
drugInventories.add(drugInventory4);

List<Drug> drugs = new ArrayList<>();

Drug drug = new Drug("121212");
Drug drug1 = new Drug("232323");
Drug drug2 = new Drug("343434");

drugs.add(drug);
drugs.add(drug1);
drugs.add(drug2);

此處的預期結果應等於如下所示的列表:

 [DrugInventory(inventoryId=454545, drugStatus=null), DrugInventory(inventoryId=565656, drugStatus=null)]

我可以在這里使用嵌套循環來比較每個元素,但這會效率低下。 我怎樣才能有效地做到這一點?

對於在庫存中查找葯品清單中不存在的葯品的具體問題,可以使用:

public static List<DrugInventory> findMissingDrugs(List<Drug> drugs, 
                                                   List<DrugInventory> inventory) {
    Set<String> drugIdLookup = drugs.stream()
                                    .map(d -> d.id)
                                    .collect(Collectors.toCollection(HashSet::new));
    return inventory.stream()
                    .filter(i->!drugIdLookup.contains(i.inventoryId))
                    .collect(Collectors.toList());      
}

首先,我們只將 ID 提取到HashSet中( HashSet提供 O(1) 查找時間復雜度),然后我們從清單中收集不在該查找集中的所有內容。 如果您有更復雜的查找需要使用多個鍵,那么關於將兩者重組為HashMap的另一個答案是 ID 是鍵的更好的長期方法。

  • 創建一個Map<String, DrugInventory>和一個Map<String, Drug> ,例如使用 HashMap 作為實現。
  • 將葯物和葯物清單對象添加到各自的 map 中,並使用每個 object 的 id 和 inventoryId 字段作為第一個參數,將 object 作為第二個參數。
  • 使用 Map 的 keySet 方法創建兩個映射的組合鍵值集。
  • 遍歷這些鍵並從相應的 map 檢索葯物和葯物庫存 object。 如果對於某個特定鍵,兩者都不為空,則您有一個匹配項,並且可以使用 System.out.println 打印出您感興趣的詳細信息。

我可以想到2個解決方案。 一個有額外空間,另一個沒有額外空間。 這是空間和時間復雜度之間的權衡,以最適合您的為准。 下面的示例代碼片段...

1. 對葯物進行排序,並對葯物庫存(inventoryId)的每個元素進行二分搜索。

    // Sort Drug by id
    Comparator<Drug> drugComparator = new Comparator<Drug>() {
        @Override
        public int compare(Drug d1, Drug d2) {
            return d1.id.compareTo(d2.id);
        }
    };

    Collections.sort(drugs, drugComparator);

    for (DrugInventory inventory : drugInventories) {
        if (!binarySearch(drugs, inventory.inventoryId)) {
            System.out.println(inventory.inventoryId);
        }
    }

    public static boolean binarySearch(List<Drug> drugs, String drugInventory) {

    int left = 0;
    int right = drugs.size() - 1;

    while (left <= right) {
        int middle = left + (right - left) / 2;
        int comapare = drugs.get(middle).id.compareTo(drugInventory);
        if (comapare == 0) {
            return true;
        } else if (comapare < 0) {
            left = middle + 1;
        } else {
            right = middle - 1;
        }
    }
    return false;
}

2.使用HashSet添加和刪除元素(id/inventoryId),set中剩余的id會丟失id。

    Set<String> set = new HashSet<String>();

    // Add drug inventories to set
    for (DrugInventory inventoryElement : drugInventories) {
        set.add(inventoryElement.inventoryId);
    }

    // Remove drugs from set
    for (Drug drugElement : drugs) {
        set.remove(drugElement.id);
    }

    // Remaining entries in set are missing entries
    Iterator iterator = set.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM