2016-12-26 66 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,姓名,時間,隨機數字和員工執行的操作。該名稱可以是一個或兩個令牌,但操作總是帶有一個令牌。我們有興趣做的是提取員工用他/她的名字執行的最後一個操作(例如: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或2,那麼得到最後一個動作。像這樣的東西。我對變種名稱做了一些改動。溫度2和溫度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