2016-10-26 39 views
0

任何想法,爲什麼contains不在這裏工作,這些語句總是評估firstSchema.contains(firstSchema.get(0))比較兩個的ArrayList的內容有效

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元素

回答

2

最簡單的方法來檢查,如果列表中包含的任何元素從另一個列表中是調用contains()在列表中的一個,每個元素傳遞如在爭論中轉。喜歡的東西:

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

這是緩慢的,但是,因爲是線性運算(O(n)),因爲我們正處在一個循環中調用它的slowListContains()功能需要二次的時間(O(n^2)),這是窮人。我們可以做得更好。

Set(或更精確地基於散列的集合如HashSet)具有在運行低於線性時間(在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步驟。

+0

真的很感謝你的努力,以解釋先生:) –

1

您正在錯誤地檢查它。請參閱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 !"); 
} 
+0

甚至'firstSchema。包含(「測試」)'也不工作:( –

+1

@Swapnil:我覺得很難相信,請發表[mcve]顯示 - 我的猜測是,你的實際測試程序有其他事情正在進行。不清楚爲什麼你使用'add'的超載需要一個索引。) –

+1

@TAsk我的壞,歉意_/\ _ –

1

如果想要檢查一個列表是否有匹配的元素,可以這樣做。

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同樣

+0

他他是很好的破解:) –

+2

這是一個破壞性的操作,它是O(n^2)運行時間。絕對不是這樣做的好方法。 – dimo414

2

您的if(!(firstSchema.contains(firstSchema)))循環錯誤。您正試圖在自己的列表中找到匹配項。你不能檢查列表是否包含它自己。下面 從Java文檔是如何包含作品

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>. 
1

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

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

爲了提高效率,如果可能的話(唯一值)(如果你有足夠的數據,它實際上很重要的工作),該secondList可以變成一個HashSet

+0

提前終止並不意味着它是有效的,它仍然在一般情況下二次運行。 – dimo414

+0

@ dimo414是的,我剛剛意識到給出的其他解決方案也不是那麼糟糕。那麼,除了'retainAll'之外。 – Kayaman