2014-03-29 21 views
1

我需要阅读scala中的一些大文本文件。然后在该文件中追加一行到StringBuilder。但是如果该文件中的行包含一些String,我需要中断循环。我不想将该String附加到StringBuilder。例如,在java中,循环A将在结果字符串中包含"pengkor"。循环B不包括该字符串,但在循环中有break语句,在scala中不可用。在循环C中,我使用了for语句,但其行为与scala中的for循环非常不同。我主要关心的是不要在StringBuilder中包含"pengkor"字符串,也不要将文件的所有内容加载到Scala列表中(因为scala中的列表理解或其他列表操作),因为文件的大小。如何在读取文件时打破scala中的循环?

public class TestDoWhile { 

    public static void main(String[] args) { 
     String s[] = {"makin", "manyun", "mama", "mabuk", "pengkor", "subtitle"}; 
     String m = ""; 
     StringBuilder builder = new StringBuilder(); 
     // loop A 
     int a = 0; 
     while (!m.equals("pengkor")) { 
      m = s[a]; 
      builder.append(m); 
      a++; 
     } 
     System.out.println(builder.toString()); 

     // loop B 
     a = 0; 
     builder = new StringBuilder(); 
     while (a < s.length) { 
      m = s[a]; 
      if (!m.equals("pengkor")) { 
       builder.append(m); 
      } else { 
       break; 
      } 
      a++; 
     } 
     System.out.println(builder.toString()); 

     // loop C 
     builder = new StringBuilder(); 
     a = 0; 
     for (m = ""; !m.equals("pengkor"); m = s[a], a++) { 
      builder.append(m); 
     } 
     System.out.println(builder.toString()); 
    } 

} 

回答

4

一种方法是用循环中的布尔值作为条件。

val lines = Source.fromPath("myfile.txt").getLines() 
val builder = new StringBuilder 
var cond = true 
while(lines.hasNext && cond) { 
    val line = lines.next 
    if(line != "pengkor") { 
    builder ++= line 
    } else cond = false 
} 
//.. do something with the builder 

另一种类似scala的方式是使用takeWhile

val lines = Source.fromPath("myfile.txt").getLines() 
val builder = new StringBuilder 
lines.takeWhile(_ != "pengkor").foreach(builder ++= _) 

你也可以看看这里:How do I break out of a loop in Scala?看到处理循环的打破的其他方式

+2

3)使用递归,很像第一种方式 –

0

你可以很容易地定义一个函数,continue而是打破

@tailrec 
def continue(buf: Array[Byte]) { 
    val read = in.read(buf); 
    if (read != -1) { 
     sb.append(parse(buf, read)) 
     continue(buf); // recur 
    } 
    // else do not recur = break the loop 
} 
continue(Array.fill(1)(0)) 

的逻辑是颠倒的:不是中断,而是为下一次迭代调用函数。开销是你需要定义一个函数并调用它。作为优势,您可以为循环提供语义名称,从功能上传递参数而不是更新变量并重用循环。