Quick Tip
Java comes with 2 useful methods for finding a sublist in a list:
Collections.indexOfSubList(List<?> source, List<?> target)
Collections.lastIndexOfSubList(List<?> source, List<?> target)
.
These are useful methods, however, with these 2 methods I can only find the first matching sublist and the last matching sublist. What about all the other sublists in between? What if there are 3 matching sublists, or 10, or 100? Here is a quick example (Listing 1) of an new, overloaded indexOfSubList(List<?> source, List<?> target, int fromIndex)
that has an extra parameter, int fromIndex
. This extra parameter gives you the ability to go through and find every matching sublist.
NOTE This code comes directly from the source code of the existing
Collections.indexOfSubList(List<?> source, List<?> target>)
method.
Listing 1 - Find all Matching SubLists
public static int indexOfSubList(List<?> source, List<?> target, int fromIndex) {
int sourceSize = source.size();
int targetSize = target.size();
int maxCandidate = sourceSize - targetSize;
ListIterator<?> si = source.listIterator();
if (fromIndex > 0) {
for (int i=0; i<fromIndex; i++) {
si.next();
}
}
nextCand:
for (int candidate = fromIndex; candidate <= maxCandidate; candidate++) {
ListIterator<?> ti = target.listIterator();
for (int i=0; i<targetSize; i++) {
if (!eq(ti.next(), si.next())) {
// Back up source iterator to next candidate
for (int j=0; j<i; j++)
si.previous();
continue nextCand;
}
}
return candidate;
}
return -1; // No candidate matched the target
}
private static boolean eq(Object o1, Object o2) {
return o1==null ? o2==null : o1.equals(o2);
}