簡體   English   中英

有效比較兩個ArrayList的內容

[英]Compare contents of two ArrayLists efficiently

不知道為什么contains不起作用,這些語句總是評估為錯誤的 firstSchema.contains(firstSchema.get(0))

    List<String> firstSchema = new ArrayList<String>();
    firstSchema.add(0,"test");
    firstSchema.add(1,"testy");

    if(!(firstSchema.contains(firstSchema))){
        System.out.println("hey arraylist content matched");
    }

如果一個arraylist中的任何一個或多個或所有元素與其他arraylist元素匹配,我需要得到true

檢查一個列表是否包含另一個列表中任何元素的最簡單方法是在其中一個列表上調用contains() ,依次將每個元素作為參數傳遞。 就像是:

public <E> boolean slowListContains(List<E> a, List<E> b) {
  for (E element : a) {
    if (b.contains(element)) {
      return true;
    }
  }
  return false;
}

但是,這很慢,因為contains()是線性運算( O(n) ),並且由於我們是在循環中調用它,因此slowListContains()函數需要二次時間( O(n^2) ),這很差。 我們可以做得更好。

一個Set (或更確切地說是一個基於哈希的集合,例如HashSet )具有一個有效的contains()方法,該方法在少於線性時間(對於HashSet而言是恆定時間)內運行。 將一個或另一個列表轉換為Set將使slowListContains()的循環快得多。 就像是:

public <E> boolean fasterListContains(List<E> a, List<E> b) {
  Set<E> aSet = new HashSet<>();
  aSet.addAll(a);
  for (E element : b) {
    if (aSet.contains(b)) {
      return true;
    }
  }
  return false;
}

這不是完美的,但肯定比幼稚的解決方案快得多。 有一點改進是始終將較小的列表轉換為Set ,而不是第一個。 您還可以采用任意Iterable參數而不是List參數,然后檢查它們中的任何一個是否已經是Set ,如果是,則跳過set-construction步驟。

您的if(!(firstSchema.contains(firstSchema)))循環是錯誤的。 您正在嘗試在列表中找到與自身的匹配項。 您無法檢查列表是否包含自身。 從下面的java doc中可以看到contains是如何工作的

  Returns <tt>true</tt> if this list contains the specified element.
  More formally, returns <tt>true</tt> if and only if this list contains
  at least one element <tt>e</tt> such that
  <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.

您檢查不正確。 請參見firstSchema.contains(firstSchema)是錯誤的arrayList.contains(arrayList)將不起作用。

其次(firstSchema.contains("test"))返回true因為數組列表確實包含test! 否定結果將不會通過if語句,因為!true = false

if(firstSchema.contains("test")) {
    System.out.println("Match found !");
}

if(!firstSchema.contains("test")) {
    System.out.println("Match not found !");
}

如果要檢查一個列表是否具有匹配的元素,則可以執行以下操作。

 List<String> firstSchema = new ArrayList<String>();
firstSchema.add(0,"test");
firstSchema.add(1,"testy");

List<String> testList = new ArrayList<String>(firstSchema);
testList.removeAll(firstSchema);

if(testList.size()<firstSchema.size()){
    System.out.println("some elements match");
}

您也可以類似地使用retainAll

最簡單的方法是使用Java 8流。

if(firstList.stream().anyMatch(secondList::contains))
    System.out.println("Content matched");

為了提高效率(如果您正在使用足夠的數據以使其真正重要),並且在可能的情況下(唯一值),可以將secondList轉換為HashSet

暫無
暫無

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

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