Java/Groovy double for statement question
This is a Java/Groovy question, im doing this function to implement in a search mechanism in my website. I have two lists:
String [] lista = temp.split() // ignore the temp part
String [] searchLista = search.split() // ignore the search part
Basically, the list开发者_C百科s are something like this:
lista = {a, b, c, d}
searchLista= {a, b, a, d}
boolean test
I want to verify if, any element on list 'lista' is the same on 'searchLista'. For that i did the following function:
for(int i = 0; i< lista.length-1; i++){
for(int j = 0; j< searchLista.length-1; j++) {
if(lista[i].contains(searchLista[j])){
test = true
##
}
}
}
My question is, if this validation is true: 'lista[i].contains(searchLista[j])', boolean variable test becomes true and next i want to jump outside both fors. A simple 'break' in the place of the ##s will do it?
(Are you deliberately missing out the last element of both lists, by the way?)
A normal break
statement would just exit the inner loop.
If you want to break two levels, there are three common options:
- Make the condition for the outer loop something which you can make false in the body
- Make the whole loop a method, and just return from it
- Use a break with a label
Example of the last option:
// Code before loop
outerLoop:
for (...) {
for (...) {
if (...) {
break outerLoop;
}
}
}
Personally I don't use labels very often - I would rather use the "make the whole double loop a method" option if possible.
If you simply want to find out whether the 2 arrays have any elements in common, the Groovyiest way to do this is:
boolean haveElementsInCommon(array, otherArray) {
!array.toList().disjoint(otherArray.toList())
}
Here are some tests for the function/method above
// create some test data
String[] list1 = [1,2,3,4]
String[] list2 = [5,6,7,8]
String[] list3 = [8,9,10,11]
// test the function works for arrays with nothing in common
assert !haveElementsInCommon(list1, list2)
// test the function works for arrays with at least one element in common
assert haveElementsInCommon(list2, list3)
You can run the code above in the Groovy Console to verify it works
The short answer is No - though the slightly longer answer is "this only affects performance, though, not correctness since test
will still be true
once you (eventually) exit the loops".
The reason is that break
only breaks out of the directly enclosing loop. In this case, you have doubly-nested loops and want to break out of both of them. One way to do this, is with a label:
OUTER: for(int i = 0; i< lista.length-1; i++){
for(int j = 0; j< searchLista.length-1; j++) {
if(lista[i].contains(searchLista[j])){
test = true
break OUTER;
}
}
}
Other alternatives would be to change to condition on the outer loop to i < l;ista.length - 1 && !test
, or to wrap this all up into a function from which you can simply return
.
Since it's Groovy however, I'd have thought there'd be a Groovier way to (lazily) calculate the intersection of two sets - at which point you can just test whether the intersection is empty or not (which is what you're really after here). It's definitely clearer to write
test = !intersection(lista, searchLista).isEmpty()
and this may be no worse in terms of performance too.
a simple break would only break the inner for loop. but you could do this in a own function and add a return statement at ##.
You could use org.apache.commons.collections.CollectionUtils.intersection(Collection, Collection)
instead. Put each array into a Set<String>
first.
The simplest way to do this with Groovy would be:
lista.any { it in searchLista }
精彩评论