Java 提取最后一个员工的最后一个操作

Java 提取最后一个员工的最后一个操作,java,string,file,stringtokenizer,Java,String,File,Stringtokenizer,假设我们有一个员工列表,其中包含员工id、姓名、时间、随机数和员工执行的操作。名称是一个或两个标记,但操作始终包含一个标记。我们感兴趣的是提取员工使用其姓名执行的最后一个操作(例如:s和sam,d和sup等) 下面的代码执行此任务,但它提取每个不同员工的第一个操作。如何修改它以满足要求 5023971 s 2016-05-22 21:34:48 5023971 s 2016-05-22 21:35:57 5023971

假设我们有一个员工列表,其中包含员工id、姓名、时间、随机数和员工执行的操作。名称是一个或两个标记,但操作始终包含一个标记。我们感兴趣的是提取员工使用其姓名执行的最后一个操作(例如:
s
sam
d
sup
等) 下面的代码执行此任务,但它提取每个不同员工的第一个操作。如何修改它以满足要求

        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
静态字符串标记器a;
公共静态布尔isInteger(字符串s){
试试{
整数.parseInt(s);
}catch(NumberFormatException | NullPointerException e){
返回false;
}
返回true;
}
静态布尔值优先=真;
公共静态void main(字符串[]args){
BufferedReader br=新的BufferedReader(文件);
弦线;
字符串名称=”;
字符串tempaction=“”;
字符串动作=”;
而((line=br.readLine())!=null){
int nameLenght=0;
字符串tempName=“”;
字符串temp2;
字符串temp3;
a=新的StringTokenizer(行);
如果(第一){
而(a.hasMoreTokens()){
temp2=a.nextToken();
temp3=temp2.charAt(0)+”;
如果((temp2).startsWith(“2016”)中断;
如果(!isInteger(临时3)){
nameLenght++;
tempName=tempName+“”+temp2;
}
}

if(nameLenght这里有一种方法可以获取每个员工的最后一个操作(使用Java8流和正则表达式匹配)

private static final Pattern LINE\u REGEX=Pattern.compile(
“^\\s*”//用户id前的空格
+“[0-9]+”//用户id
+“\\s+”//用户id后的空格
+“(.*?[^\\s])”//用户名(组1)
+“\\s+”//用户名后的空格
+“([0-9]+-.{14})”//时间戳(第2组)
+“\\s+”//时间戳后的空格
+“[0-9]*”//随机整数
+“\\s+”//随机整数后的空格
+“(.[^\\s])”//用户操作(组3)
+“\\s*$”//用户操作后的空格
);
公共静态void main(字符串[]args)引发IOException{
try(Stream=Files.line(path.get(“emplog.txt”)){
Map result=stream.Map(行_REGEX::matcher)
//无需操作即可过滤掉任何行
.filter(Matcher::matches)
//按用户分组
.collect(收集器.groupingBy((匹配器m)->m.group(1),
收藏,收藏,然后(
//比较时间戳(最早为最小值,最晚为最大值)
收集器.maxBy(比较器比较((匹配器m)->m.group(2)),
//提取作用
(可选m)->m.get().group(3));
系统输出打印项次(结果);
}
}
输出:

{s=sple,d=sup,ga=gglrt,ya=hnd,rl=roy}


(如果任何用户没有任何操作,则不会列出。)

当变量有无意义的名称时,很难遵循您的逻辑,如
temp
temp2
temp3
tent
等。此外,这是一种固定长度的字段格式。使用字符串标记器处理它不是一个好主意。如果您按字段的位置抓取字段,逻辑会简单得多在线上。@RealDis疑论者,但是员工的名字不是固定的,他们的长度比一长。所以我必须先计算长度。如果是1或2,那么就得到最后一个动作。类似这样。我对变量的名字做了一些更改。临时2和临时3是不重要的部分(ID、日期和时间)。在您提供的文件中,employee name字段是固定的-它始终是3个字符,尽管其中一些字符可能是空格。@不,第一个整数是ID,然后有一个或两个字母作为名称。(从左到右。右边最后一个常见的字符是操作。)仔细看。你总是可以取整数后面的三个字母。它们可以是一个字母和两个空格,也可以是一个字母、一个空格和一个字母。它总是三个字符。同样,根据你在这里发布的文件。筛选(Matcher::matches)获取用于在静态方法中调用非静态方法的无效引用。我不知道为什么它在实际日志中不起作用。可能是因为在实际日志中,名称是完整的?比如David而不是d?或者有其他解释?哦,我找到了它不起作用的原因。在实际日志中,名称之间还有一些空格每列。你能告诉我如何修改你的代码以忽略这些空格吗?@user3049183我已经对regexp添加了一些注释和修改。现在再试一次。别忘了更新有用的答案并接受正确的答案。另外,由于你不能提供文件的确切空格结构,我不得不依靠一些混蛋例如,假设操作不能以后跟空格的整数开头(这将匹配随机整数部分)。
 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;
                    }
                    }
    }
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);
    }
}