我是Java 8的新手,正在尝试对Streams的需求。我有一个带有数千个Recod的csv文件,我的csv格式是

DepId,GrpId,EmpId,DepLocation,NoofEmployees,EmpType
===
D100,CB,244340,USA,1000,Contract
D101,CB,543126,USA,1900,Permanent
D101,CB,356147,USA,1800,Contract
D100,DB,244896,HK,500,SemiContract
D100,DB,543378,HK,100,Permanent

My requirement is to filter the records with two conditionsa) EmpId starts with "244" or EmpId starts with "543"b) EmpType is "Contract" and "Permanent"

I tried below

 try (Stream<String> stream = Files.lines(Paths.get(fileAbsolutePath))) {
    list = stream
        .filter(line -> line.contains("244") || line.contains("543"))
        .collect(Collectors.toList());
     }

它基于244和543过滤员工,但是我担心的是,因为我使用的包含它可能还会获取其他数据,即它将不仅从EmpId列而且从其他列获取数据(其他列也可能以这些数字)

类似地,因为我正在逐行阅读中合并EmpType,所以我无法强制EmpType应该位于“Permanent”和“Contract”中

我是否缺少任何高级选项?

最佳答案

你可以这样做

Pattern comma = Pattern.compile(",");
Pattern empNum = Pattern.compile("(244|543)\\d+");
Pattern empType = Pattern.compile("(Contract|Permanent)");
try (Stream<String> stream = Files.lines(Paths.get("C:\\data\\sample.txt"))) {
    List<String> result = stream.skip(2).map(l -> comma.split(l))
            .filter(s -> empNum.matcher(s[2]).matches())
            .filter(s -> empType.matcher(s[5]).matches())
            .map(s -> Arrays.stream(s).collect(Collectors.joining(",")))
            .collect(Collectors.toList());
    System.out.println(result);
} catch (IOException e) {
    e.printStackTrace();
}

首先读取文件,并跳过2个标题行。然后使用,字符将其拆分。使用EmpIdEmpType过滤掉它。接下来,再次合并 token 以形成行,最后将每行收集到List中。

09-30 17:43
查看更多