2016-10-26 5 views
0

Любая идея, почему contains не работает здесь, это утверждение всегда оценки ложныеfirstSchema.contains(firstSchema.get(0))Сравните содержимое двух ArrayLists эффективно

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, и если это так, пропустите шаг установки-построения.

+0

Действительно оцените ваши усилия для объяснения Sir :) –

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

даже если "первыйSchema.содержит («test») 'также не работает :( –

+1

@Swapnil: Мне очень трудно поверить. Пожалуйста, опубликуйте [mcve], показывая, что - я предполагаю, что в вашей реальной тестовой программе есть что-то еще. (Это также непонятно, почему вы используете перегрузку 'add', которая принимает индекс.) –

+1

@TAsk my bad, Apologies _/\ _ –

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 Да, я просто понял, что другие предлагаемые решения не так уж и плохи. Ну, кроме 'keepAll'. – Kayaman

Смежные вопросы