Мне нужно прочитать большой текстовый файл в scala. И добавьте строку в этот файл в StringBuilder
. Но мне нужно разбить цикл, если строка в этом файле содержит некоторую строку. И я не хочу добавлять эту строку в StringBuilder. Например, в java цикл A
будет содержать "pengkor"
в приведенной строке. Loop B
не включает эту строку, но в цикле есть оператор break
который недоступен в scala. В цикле C я использовал for
оператора, но с поведением, которое очень отличается for
цикла в scala. Моя основная задача - не включать "pengkor"
строку "pengkor"
и не загружать весь контент файла в Scala List (для целей понимания List в 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());
}
}
Один из способов сделать это - с булевым как условие в цикле.
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 ++= _)
Вы также можете посмотреть здесь: Как я вырваться из цикла в Scala? увидеть другие способы борьбы с разрывом цикла
Вы можете легко определить функцию и 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))
Логика инвертируется: вместо нарушения вы вызываете функцию для следующей итерации. Накладные расходы - это то, что вам нужно определить функцию и вызвать ее. В качестве преимущества вы можете дать семантическое имя для своего цикла, функционально передать аргументы вместо обновления переменных и повторного использования цикла.