2015-09-30 1 views
3

Я прочитал в groovy how to check if a list contains a sublist - stackoverflow.Как проверить, содержит ли список подсписок в заданном порядке в Java

Меня интересует, есть ли способ проверить, содержит ли список подписок, но в данном порядке. Например, этот код будет давать истинную,

List<String> list = Arrays.asList("PRP", "VBP", "VBN", "NN", "NNS", "MD", "VB"); 
    List<String> sublist = Arrays.asList("MD", "VB", "VBN"); 
    System.out.println(list.containsAll(sublist)); 

Но я хочу, чтобы получить ложных назад.

+0

отладить его ....... – Mohit

+1

итерация. Прямого пути нет. – ergonaut

+0

@ergonaut, пожалуйста, проверьте мой ответ ... java имеет некоторые встроенные функции, которые не известны –

ответ

12

Вы можете использовать метод Collections.indexOfSubList.

Возвращает начальную позицию первого вхождения указанного целевого списка в указанном списке источников или -1, если такого возникновения нет. Более формально, возвращает самый низкий индекс i такой, что source.subList(i, i+target.size()).equals(target), или -1, если такого индекса нет. (Возврат -1 если target.size()>source.size().)

int index=Collections.indexOfSubList(list , sublist); 

SHORT:
Если Collections.indexOfSubList(list , sublist) =! -1 у вас будет матч

+1

Спасибо, это то, что мне нужно. – anamar

1

Дешевые, но некрасиво решение:

String listStr = list.toString().replace("[", "").replace("]", ""); 
String sublistStr = sublist.toString().replace("[", "").replace("]", ""); 

System.out.println(listStr.contains(sublistStr)); 
+0

проверить мое решение, 'Коллекции' твой друг/mira't la meva sol.lució,' Коллекции' es el teu amic;) –

+0

Я согласен 100%, я использую Apache Commons каждый день :-) –

+0

фактически 'Коллекции' не Apache Commons ....;) –

0

Не совсем понятно, из вашего вопроса: если подсписок может содержаться в списке в orde г, но и с другими элементами между ними, вы можете использовать что-то вроде этого:

public static <T> boolean containsInOrder(List<T> list, List<T> sublist) { 
    Iterator<T> listIter = list.iterator(); 
    for (T item : sublist) { 
     if (! listIter.hasNext()) { 
      // still elements in sublist, but none in list 
      return false; 
     } 
     while (listIter.hasNext() && ! listIter.next().equals(item)) { 
      // do nothing, just consume the list until item is found 
     } 
    } 
    // entire sublist found in list 
    return true; 
} 

С list = ["PRP", "VBP", "VBN", "NN", "NNS", "MD", "VB"], это возвращает false для sublist = ["MD", "VB", "VBN"] и true для sublist = ["PRP", "VBN", "VB"].

+1

Я не допускаю других элементов между ними. @JordiCastilla предоставила решение, которое я искал. – anamar

0

Я счел необходимым прокомментировать, что решение @JordiCastilla неверно в том смысле, что оно завершено. Это может быть правильно, если тип элемента имеет правильные значения, потому что в случае Collections.indexOfSubList вы вызываете тип элемента списка равно.

/** 
* Compares the specified object with this list for equality. Returns 
* <tt>true</tt> if and only if the specified object is also a list, both 
* lists have the same size, and all corresponding pairs of elements in 
* the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and 
* <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null : 
* e1.equals(e2))</tt>.) In other words, two lists are defined to be 
* equal if they contain the same elements in the same order. This 
* definition ensures that the equals method works properly across 
* different implementations of the <tt>List</tt> interface. 
* 
* @param o the object to be compared for equality with this list 
* @return <tt>true</tt> if the specified object is equal to this list 
*/ 
boolean equals(Object o); 

Это, однако, тривиально зависит от культуры, а в случае типа Строка неверно. Рассмотрим, например, случай:

String a = "ss"; 
String b = "ß";     //german "ss" character 
Assert.IsTrue(a.equals(b));  //in java, this will return false even in DE locale 

Я думаю, рассуждения за ней в том, что количество символов не соответствует - ни в коем случае не является правильным. Можно было бы подумать, что «по крайней мере, они получили основы вниз вправо» - и было бы неправильно:

«Вы должны знать, что интернационализация и локализация вопросы полных строк Unicode не рассматриваются с [String] методами Например, при сравнении двух строк для определения того, что является «больше», символы в строках сравниваются численно по значениям Unicode , а не по их локализованному понятию порядка."

В Unicode однако же строка может иметь несколько представлений, и они не будут приравнивать строковый тип является примером, но вы можете иметь любой тип данных

Короче говоря:.. Убедитесь, ваш тип элемента равняется имеет правильную реализацию


Другой пример того, как это может быть тривиальным неправильно выглядит следующим образом:.

List arrlistsrc = new ArrayList(); 
List arrlisttarget = new ArrayList(); 

arrlistsrc.add("A"); 
arrlistsrc.add("B"); 
arrlistsrc.add("C"); 

arrlisttarget.add("A"); 
arrlisttarget.add("C"); 

int index = Collections.indexOfSubList(arrlistsrc, arrlisttarget); // this will be -1 

Первый список содержит второй, и они имеют один и тот же порядок, но между элементами целевых элементов источник содержит другие элементы.

Чтобы найти, что вы можете использовать что-то в строках:

boolean ContainsOrderedSublist<T>(IList<T> arrlistsrc, IList<T> arrlisttarget){ 
    int slider = 0; 
    for (String val: arrlisttarget) { 
     slider = arrlistsrc.indexOf(val, slider);// or use culture independent version 
     if(slider < 0) break; 
    } 
    return slider < 0;  
} 

(NB: примеры кода не испытанные и написанные от головы)

+0

Почему 'ss' считается равным' ß'? 'ß' - это не только типографская лигатура, но и другая буква. «в Массене» имеет совершенно иное произношение _and_ значение, чем «в Массене». Кроме того, почему, по вашему мнению, это будет иметь отношение к делу OP? О вашем «другом примере»: так я тоже понял этот вопрос, но, видимо, его неправильно ... –

+0

Во втором случае я хотел указать, что {A, B, C} содержит упорядоченный список {A, C}, но элементы не являются следствием. В первом случае я хотел указать на то, что равенство имеет культурную составляющую, и большинство из них об этом забывают. Вы можете придумать лучший пример из прихоти, а с другой - нет. Кроме того, для контраста в C# .Net ** «Strasse» .Equals («Straße», StringComparison.InvariantCulture); ** ** вернет ** true ** (то же самое для CompareTo). – Margus

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