我正在使用“java.util.Scanner”来读取和扫描关键字,并希望打印遇到的关键字的前 5 行和后 5 行,下面是我的代码
ArrayList<String> keywords = new ArrayList<String>();
keywords.add("ERROR");
keywords.add("EXCEPTION");
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int count = 0;
String previousLine = null;
while(input.hasNext()){
String line = input.nextLine();
for(String keyword : keywords){
if(line.contains(keyword)){
//print prev 5 lines
system.out.println(previousLine); // this will print only last previous line ( i need last 5 previous lines)
???
//print next 5 lines
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
}
previousLine = line;
}
打印前 5 行的任何指针..?
最佳答案
any pointers to print previous 5 lines..?
- 将它们保存在
Dequeue<String>
中例如LinkedList<String>
因为它的“先进先出(FIFO)”行为。 - 要么使用 5 个变量,要么使用 5 个字符串的数组,手动将字符串从一个槽或变量移动到另一个槽或变量,然后打印它们。
- 如果您使用 Dequeue/LinkedList,请使用 Dequeue 的
addFirst(...)
方法将新字符串添加到开头和removeLast()
删除列表的最后一个字符串(如果其大小 > 5)。遍历 LinkedList 以获取它包含的当前字符串。
其他建议:
- 您的扫描仪支票
scanner.hasNextXXX()
方法应与 get 方法匹配,scanner.nextXXX()
.所以你应该检查hasNextLine()
如果你要调用nextLine()
.否则,您可能会遇到问题。 - 请尝试在您的问题中在这里发布真实代码,而不是某种形式,永远不会编译代码。即
system.out.println
对比System.out.println
.我知道这是一件小事,但当其他人尝试使用您的代码时,这意味着很多。 - 使用 ArrayList 的
contains(...)
摆脱 for 循环的方法。
例如,
LinkedList<String> fivePrevLines = new LinkedList<>();
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (input.hasNextLine()) {
String line = input.nextLine();
if (keywords.contains(line)) {
System.out.println("keyword found!");
for (String prevLine : fivePrevLines) {
System.out.println(prevLine);
}
} else {
fivePrevLines.addFirst(line);
if (fivePrevLines.size() > 5) {
fivePrevLines.removeLast();
}
}
}
if (input != null) {
input.close();
}
编辑
您在评论中声明:
ok i ran small test program to see if the contains(...) method works ...
<unreadable unformatted code>
... and this returned keyword not found...!
一切在于你如何使用它。 contains(...)
方法用于检查 Collection 是否包含另一个对象。如果您向它提供一个可能使用也可能不使用集合中的其中一个字符串的巨大字符串,它将无法工作,但可以处理构成较大字符串的各个字符串。例如:
ArrayList<String> temp = new ArrayList<String>();
temp.add("error");
temp.add("exception");
String s = "Internal Exception: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object";
String[] tokens = s.split("[\\s\\.:,]+");
for (String token : tokens) {
if (temp.contains(token.toLowerCase())) {
System.out.println("keyword found: " + token);
} else {
System.out.println("keyword not found: " + token);
}
}
此外,您将希望避免在评论中发布代码,因为它们不保留其格式并且不可读且不可测试。而是编辑您的原始问题并发表评论以提醒我们进行编辑。
编辑2
根据 dspyz:
For stacks and queues, when there isn't any significant functionality/performance reason to use one over the other, you should default to ArrayDeque rather than LinkedList. It's generally faster, takes up less memory, and requires less garbage collection.
关于Java Scanner 打印上一行和下一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17734606/