【问题标题】:Java/Groovy double for statement questionJava/Groovy double 语句问题
【发布时间】:2011-05-25 15:11:23
【问题描述】:

这是一个 Java/Groovy 问题,我正在执行此功能以在我的网站的搜索机制中实现。我有两个列表:

String [] lista = temp.split() // ignore the temp part
String [] searchLista = search.split() // ignore the search part

列表基本上是这样的:

    lista = {a, b, c, d}
    searchLista= {a, b, a, d}
    boolean test

我想验证列表“lista”上的任何元素是否与“searchLista”上的相同。为此,我做了以下功能:

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
                        ##
                    }
                }
            }

我的问题是,如果此验证为真:'lista[i].contains(searchLista[j])',布尔变量测试变为真,接下来我想跳出两个 fors。一个简单的“break”代替##s 就可以了?

【问题讨论】:

    标签: java groovy


    【解决方案1】:

    (顺便说一句,您是否故意遗漏了两个列表的最后一个元素?)

    普通的break 语句只会退出内部循环。

    如果你想打破两个层次,有三种常见的选择:

    • 使外循环的条件可以在正文中设置为假
    • 使整个循环成为一个方法,然后从它返回
    • 使用带标签的中断

    最后一个选项的示例:

    // Code before loop
    outerLoop:
    for (...) {
        for (...) {
            if (...) {
                break outerLoop;
            }
        }
    }
    

    我个人不经常使用标签 - 如果可能,我宁愿使用“使整个双循环成为方法”选项。

    【讨论】:

    • 标签与goto 非常相似,我们都知道“Go To Statement被认为有害”(但也有“'Go To Statement被认为有害'被认为有害”等):)
    • @Michael:我认为它不像 goto 那样随意......但我仍然更喜欢更简单的方法。
    • “Go To 语句在谨慎且适当地使用时被认为非常方便”我猜它并没有那么吸引人
    【解决方案2】:

    如果您只是想找出这两个数组是否有任何共同的元素,那么 Groovyiest 的方法是:

    boolean haveElementsInCommon(array, otherArray) {
      !array.toList().disjoint(otherArray.toList())
    }
    

    这里是对上述函数/方法的一些测试

    // 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)
    

    您可以在Groovy Console 中运行上面的代码来验证它是否有效

    【讨论】:

      【解决方案3】:

      简短的回答是否定的 - 尽管稍长一点的答案是“这只会影响性能,但不会影响正确性,因为一旦您(最终)退出循环,test 仍将是true”。

      原因是break 只跳出直接封闭的循环。在这种情况下,您有双重嵌套的循环,并希望摆脱它们。一种方法是使用标签:

      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;
            }
         }
      }
      

      其他替代方法是将外部循环上的条件更改为i &lt; l;ista.length - 1 &amp;&amp; !test,或者将其全部包装到一个函数中,您可以从中简单地使用return

      但是,由于它是 Groovy,我原以为会有一种 Groovier 方法来(懒惰地)计算两组的交集——此时您可以测试交集是否为空(这就是您'真的在这里)。 确实写得更清楚了

      test = !intersection(lista, searchLista).isEmpty()
      

      这在性能方面也可能不会更差。

      【讨论】:

        【解决方案4】:

        一个简单的 break 只会破坏内部的 for 循环。 但您可以在自己的函数中执行此操作并在 ## 处添加 return 语句。

        【讨论】:

          【解决方案5】:

          您可以改用org.apache.commons.collections.CollectionUtils.intersection(Collection, Collection)。先将每个数组放入Set&lt;String&gt;

          【讨论】:

            【解决方案6】:

            使用 Groovy 执行此操作的最简单方法是:

            lista.any { it in searchLista }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-06-16
              • 1970-01-01
              • 2020-06-20
              • 1970-01-01
              • 2013-10-24
              • 1970-01-01
              • 2021-10-09
              • 2010-09-25
              相关资源
              最近更新 更多