簡體   English   中英

比較不同類型的對象列表的有效方法

[英]Efficient way to compare different types of List of Objects

public class State{

String code;
int occurValue;
int name;

}

public class Equi{
String code;
int occurValue;
int macAddress;

}

具有2個不同類型的類別。 我有一個List<State>List<equi> 在這些列表中,如果代碼和existValue相同,則需要將其移至其他列表。 我怎么能做到這一點,谷歌搜索給了我這么多選擇線比較器,比較器。 讓我知道哪種方法最有效。 提前致謝。

我將使用自己定義的方法來執行此操作,或者使用Boolean <compare(State state, Equi equi)>或類似的方法,將給定的列表項作為參數。 和代碼:

//You have to iterate the method with a for loop for example
//In different situations you need different iterating methods, for example you add 
//1 element to Equi:
//You compare all State element with the new Equi element, but just with that ONE
for (int i =0; i < stateList.size(); i++ {
  flag = compare(stateList.get(i),equiList.get(<indexOfNewElement>); // flag is a boolean value
  if (flag) {
    //moving metod and stuff...
  }
}
//this way you don't make unnecessary steps. It's one example, there are many other situation

Boolean compare(State state, Equi equi) { // You add List elements as parameters
  if (state.getCode().equals(equi.getCode())) { // I prefer to use getters, it depends on your code and preferences
    if (state.getOccurValue() == equi.getOccurValue()) { //same here
      return true; //If returns true, an other method move it.
    } else {
      return false;
    }
  } else { //if the first ones aren't equal needless to check the second values
    return false;
  }
}

這樣,您可以使用此方法進行所有比較,但是每次需要編寫迭代器時。 這意味着更多的編碼,但運行時間更少。 例如,如果列表按code以ABC順序排序,則可以避免使用標記或其他任何東西將“ k *”與“ a *”進行比較。

這在很大程度上取決於您對“效率”的定義。

如果您對時間不感興趣,則可以創建一個雙重foreach循環並將每個項目相互比較。 這是蠻力的,並且不節省時間(因為它是O(n ^ 2)) ,但是可以節省大量的編程時間,您可以花在一些更有用的東西上。 數量很少的商品(我建議<10.000)也是如此,而時間優化通常是不付錢的。

如果您希望節省時間,可以使用一些抽象的數據結構來幫助您。 例如,如果“代碼”字段在每個集合中都是唯一的,則創建一個HashMap ,其中鍵引用“代碼”,並且值是Equi引用。 然后,您可以遍歷您的州,並在HashMap中查詢匹配的Equi。 向返回的Equi詢問發生值。 您還可以引入另一個第二個HashMap,其中將elseValues作為鍵。 比較部分應為O(n)。

您將采用一種更加面向對象的方法來創建接口IHasCodeAndOccurValue,並讓State和Equi實現該接口。 然后在兩個類中實現equals(IHasCodeAndOccurValue other)方法。 您將兩個數據集都插入到一個List中,然后調用stateList.retainAll(equiList)。 這可能是最優雅的方法,並且-取決於您選擇的List實現- 也可以在O(n)中運行

如您所見,有幾種優化此代碼的方法。 不知道細節,純粹是猜測如何進行。

如果列表上沒有其他信息,那么最有效的算法是將一個列表的每個元素與另一個列表的每個元素進行比較:

for (State s : stateList) {
    for (equi e : equiList) {
        if (s.code.equals(e.code) && s.occurValue == e.occurValue) {
            // add to another list
        }
    }
}

這是O(n * m)(其中n是stateList的大小,m是equiList的大小)。

如果對兩個列表進行了排序,則可以使用更有效的算法。 例如,用偽代碼:

for (int i = 0; i < stateList.size(); i++) {
    int j = 0;
    State s = stateList.get(i);
    while (equiList.get(j) is smaller than s) {
        j++;
    }
    equi e = equiList.get(j);
    if (s.code.equals(e.code) && s.occurValue == e.occurValue) {
        // add to another list
    }
}

這是O(m + n)。 當然,要做到這一點,您將必須編寫比較功能(一個用於將一個State與一個State進行比較,一個用於將一個equi與一個equi進行比較以及一個用於將一個State與一個equi進行比較的函數)。

順便說一句,Java命名約定規定類以大寫字母開頭,因此應該為Equi而不是equi

暫無
暫無

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

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