簡體   English   中英

在列表中搜索價值的最快,最優化的方法<T>

[英]Fastest and optimized way to search for value in a List<T>

我有一個List<Person> persons = new ArrayList<Person>() ,此列表的大小為100+。 我要檢查此列表中是否包含特定的personID對象。 目前,我正在以這種方式:

for(Person person : persons) 
{
    for(Long pid : listOfIDs) 
    {
        if(person.personid == pid) 
        {
            // do somthing 
        } 
        else
        {
            // do somthing 
        }
    } // end of inner for
} 

但是我不想遍歷listOfIDs每個元素的persons列表。 我想到將personid的Person HashMap作為鍵,並將Person對象作為值。 這樣我只能遍歷listOfIDs並檢查contains()

還有其他方法嗎?

如果列表過長,則使用嵌套循環的實現將無法很好地擴展。 您將要執行的操作數是兩個列表的長度的乘積。

如果您的列表中至少有一個按ID排序,則可以使用二進制搜索。 這將是對嵌套循環的改進。

制作Map是個好主意,並且可以很好地擴展。 使用此技術,您將遍歷“人員”列表一次以構建地圖,然后遍歷“ ID”列表一次以進行查找。 確保使用Persons的數量初始化HashMap的大小(這樣,在將Persons放入Map中時不必重新哈希)。 這是一個非常可擴展的選項,不需要對任何一個列表進行排序。

如果兩個列表碰巧都按ID排序,那么您還有另一種有吸引力的選擇:一起沿着兩個列表走。 您將從兩個列表的開頭開始,然后在ID最小的列表中向前移動。 如果這些ID相等,則您要執行業務邏輯以找到具有該ID的人並在兩個列表中都向前邁進。 一旦到達任一列表的末尾,就完成了。

Java的Collections提供了非常快速的二進制搜索,但是它假定您正在搜索列表的成員。 您可以使用自己的ID標准來實現自己的目標:

Collections.sort(persons, (p1, p2) -> p1.personID - p2.personID);
if (binarySearch(persons, id)) {
    ...
}

boolean binarySearch(List<Person> personList, Long id) {
    if (personList.empty())
        return false;
    long indexToTest = personList.size() / 2;
    long idToTest = personList.get(indexToTest).personID;
    if (idToTest < id) 
        return binarySearch(personList.subList(indexToTest + 1, personList.size());
    else if (idToTest > id)
        return binarySearch(personList.subList(0, indexToTest));
    else
        return true;
}

如果您不想對列表進行排序,則可以將其復制到排序列表中並在其上進行搜索:對於大型列表,這仍然比遍歷列表快得多。 實際上,這與保留單獨的哈希圖非常相似(盡管哈希圖可能會更快)。

如果必須迭代,那么至少可以使用並行流來利用多個內核(如果有):

if (persons.parallelStream().anyMatch(p -> p.personID == id)) {
    ...
}

暫無
暫無

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

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