2016-12-26 11 views
0
 5023971 s 2016-05-22 21:34:48  
     5023971 s 2016-05-22 21:35:57  
     5023971 s 2016-05-22 21:36:35  
     5023971 s 2016-05-22 21:37:42  
     5023971 s 2016-05-22 21:39:41 3 sple 
     5296256 d 2016-03-04 08:05:12  
     5296256 d 2016-03-04 08:05:13  
     5296256 d 2016-03-04 08:05:14 4 sup 
     5324887 d 2016-05-06 10:22:22  
     5324887 d 2016-05-06 10:22:30 2 sup 
     79159 r l 2016-03-13 16:33:59 1 roy 
     1318887 g a 2016-03-15 11:59:09 2 gg 
     1318887 g a 2016-03-21 13:26:13 1 gglrt 
     4821757 y a 2016-05-24 19:46:39 8 hnd 

従業員のID、名前、時刻、乱数、従業員の行動を含む従業員のリストがあるとします。名前は1つまたは2つのトークンですが、アクションは常に1つのトークンで構成されます。私たちが関心を持つのは、従業員が最後に行った行動を抽出することです(例えば、ssamdsupなど) 以下のコードは仕事をしますが、それぞれ異なる従業員。どのように要件を満たすためにそれを変更するには?ここで最後の従業員の最後のアクションの抽出

static StringTokenizer a; 
public static boolean isInteger(String s) { 
try { 
    Integer.parseInt(s); 
} catch(NumberFormatException | NullPointerException e) { 
    return false; 
} 
    return true; 
} 

static boolean first=true; 

    public static void main(String[] args) { 


    BufferedReader br=new BufferedReader(file); 

    String line; 
    String name=""; 
    String tempaction=""; 
    String action=""; 

    while((line=br.readLine())!=null){ 

        int nameLenght=0; 
        String tempName=""; 
        String temp2; 
        String temp3; 
        a=new StringTokenizer(line); 

        if(first){ 
        while(a.hasMoreTokens()){ 
         temp2=a.nextToken(); 
         temp3=temp2.charAt(0)+""; 
         if((temp2).startsWith("2016")) break; 
         if(!isInteger(temp3)){ 
          nameLenght++; 
          tempName=tempName+" "+temp2; 

         } 


        } 
         if(nameLenght<3 && !name.equals(tempName)){ 

          name=tempName; 
          System.out.println(name); 
          first=false; 
         } 
        } 

        action=""; 
        if(!first){ 
         while(a.hasMoreTokens()){ 

         temp2=a.nextToken(); 
         temp3=temp2.charAt(0)+""; 
         if((temp2).startsWith("2016")) break; 
         if(!isInteger(temp3)){ 
          action=action+" "+temp2; 

         }      

        } 

         if(!tempAction.equals(action)){ 
          tempAction=action; 
          System.out.println(action); 
          first=true; 
          } 

         first=true; 
        } 
        } 
    } 
+0

変数に 'temp'、' temp2'、 'temp3'、' tempT'などの無意味な名前があると、あなたのロジックに従うのは本当に難しいです。さらに、これは固定長のフィールド形式です。文字列トークナイザで処理するのは良い考えではありません。ライン上の位置によってフィールドを取得すると、ロジックがはるかに簡単になります。 – RealSkeptic

+0

@RealSkepticしかし、従業員の名前は固定されていません。長さが1よりも長くなっています。だから私は長さを数えなければならない。 1または2の場合は、最後のアクションを取得します。このようなもの。そして、私はvarsの名前にいくつかの変更を加えました。 temp 2とtemp 3は、重要でない部分(IDと日付と時刻)です。 – user3049183

+0

あなたが指定したファイルでは、従業員名フィールドは固定されていますが、そのうち3つは常に空白ですが、そのうちのいくつかはスペースです。 – RealSkeptic

答えて

0

各従業員のための最後のアクションを得るための一つの方法(Javaの8つのストリームと正規表現のマッチングを使用して)

private static final Pattern LINE_REGEX = Pattern.compile(
     "^\\s*" // space before user id 
     + "[0-9]+" // user id 
     + "\\s+" // space after user id 
     + "(.*?[^\\s])" // user name (group 1) 
     + "\\s+" // space after user name 
     + "([0-9]+-.{14})" // timestamp (group 2) 
     + "\\s+" //space after timestamp 
     + "[0-9]*" // random int 
     + "\\s+" //space after random int 
     + "(.*[^\\s])" // user action (group 3) 
     + "\\s*$" // space after user action 
); 
public static void main(String[] args) throws IOException { 
    try(Stream<String> stream = Files.lines(Paths.get("emplog.txt"))) { 
     Map<String,String> result = stream.map(LINE_REGEX::matcher) 
      // filter out any lines without an Action 
      .filter(Matcher::matches) 
      // group by User 
      .collect(Collectors.groupingBy((Matcher m) -> m.group(1), 
       Collectors.collectingAndThen(
        // compare Timestamp (min for earliest, max for latest) 
        Collectors.maxBy(Comparator.comparing((Matcher m) -> m.group(2))), 
        // extract Action 
        (Optional<Matcher> m) -> m.get().group(3)))); 
     System.out.println(result); 
    } 
} 

が出力されます。

{S = SPLE 、d = sup、ga = gglrt、ya = hnd、rl = roy}

(ユーザーが何もしていない場合、リストには表示されません)

+0

filter(Matcher :: matches)は、静的メソッド内で非静的メソッドを呼び出すための無効な参照を取得します。 – user3049183

+0

私はなぜそれが実際のログで動作していないのかわかりません。実際のログでは名前が完全であるためでしょうか? dの代わりにダビデのように?または何か他の説明がありますか? – user3049183

+0

ああ、私はそれが働いていない理由を見つけました。実際のログでは、各列の間に空白があります。これらの空白を無視するようにコードを修正する方法を教えてください。 – user3049183

関連する問題