3

「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 行を印刷するためのポインタはありますか?

4

2 に答える 2

3

前の 5 行を印刷するためのポインタはありますか?

  • 「先入れ先出し (FIFO)」動作Dequeue<String>のために、 などに保存します。LinkedList<String>
  • それか、5 つの変数または 5 つの文字列の配列を使用して、文字列をあるスロットまたは変数から別のスロットまたは変数に手動で移動し、それらを出力します。
  • Dequeue/LinkedList を使用する場合は、Dequeue のaddFirst(...)メソッドを使用して新しい文字列を先頭に追加しremoveLast()、リストの最後の文字列を削除します (サイズが 5 より大きい場合)。LinkedList を反復処理して、含まれている現在の文字列を取得します。

その他の提案:

  • スキャナの checkscanner.hasNextXXX()メソッドは get メソッドと一致する必要がありscanner.nextXXX()ます。hasNextLine()そのため、電話するかどうかを確認する必要がありますnextLine()。そうしないと、問題が発生する危険があります。
  • コードをコンパイルすることはありません。すなわち、system.out.printlnSystem.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();
  }


コメントであなたの状態を編集します:

わかりました、小さなテスト プログラムを実行して、contains(...) メソッドが機能するかどうかを確認しました... <unreadable unformatted code>...そして、この返されたキーワードが見つかりません...!

それはあなたがそれをどのように使うかです。このcontains(...)メソッドは、コレクションに別のオブジェクトが含まれているかどうかを確認するために機能します。コレクション内のいずれかの文字列を使用する場合と使用しない場合がある巨大な文字列をフィードしても機能しませんが、より大きな文字列を構成する個々の文字列に対しては機能します。例えば:

  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に従って:

スタックとキューの場合、どちらか一方を使用する重要な機能/パフォーマンス上の理由がない場合は、デフォルトで LinkedList ではなく ArrayDeque を使用する必要があります。一般的に高速で、メモリの消費量が少なく、必要なガベージ コレクションも少なくなります。

于 2013-07-18T21:55:14.177 に答える