java scanner和for,Java Scanner打印上一行和下一行

I am using 'java.util.Scanner' to read and scan for keywords and want to print the previous 5 lines and next 5 lines of the encountered keyword, below is my code

ArrayList keywords = new ArrayList();

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;

}

any pointers to print previous 5 lines..?

解决方案

any pointers to print previous 5 lines..?

Save them in an Dequeue such as a LinkedList for its "First In First Out (FIFO)" behavior.

Either that or use 5 variables or an array of 5 Strings, manually move Strings from one slot or variable to another, and then print them.

If you use Dequeue/LinkedList, use the Dequeue's addFirst(...) method to add a new String to the beginning and removeLast() to remove the list's last String (if its size is > 5). Iterate through the LinkedList to get the current Strings it contains.

Other suggestions:

Your Scanner's check scanner.hasNextXXX() method should match the get method, scanner.nextXXX(). So you should check for hasNextLine() if you're going to call nextLine(). Otherwise you risk problems.

Please try to post real code here in your questions, not sort-of, will never compile code. i.e., system.out.println vs System.out.println. I know it's a little thing, but it means a lot when others try to play with your code.

Use ArrayList's contains(...) method to get rid of that for loop.

e.g.,

LinkedList 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();

}

Edit

You state in comment:

ok i ran small test program to see if the contains(...) method works ...... and this returned keyword not found...!

It's all how you use it. The contains(...) method works to check if a Collection contains another object. It won't work if you feed it a huge String that may or may not use one of the Strings in the collection, but will work on the individual Strings that comprise the larger String. For example:

ArrayList temp = new ArrayList();

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

}

}

Also, you will want to avoid posting code in comments since they don't retain their formatting and are unreadable and untestable. Instead edit your original question and post a comment to alert us to the edit.

Edit 2

As per 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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值