Java8流多过滤器

Java8流多过滤器,java,filter,java-stream,Java,Filter,Java Stream,我是Java8新手,正在尝试一个关于流的需求。我有一个包含数千个记录的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,5

我是Java8新手,正在尝试一个关于流的需求。我有一个包含数千个记录的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 DepId、GrpId、EmpId、DEPPLOCATION、NoofEmployees、EmpType === D100,CB,244340,美国,1000,合同 D101,CB,543126,美国,1900,永久 D101,CB,356147,美国,1800,合同 D100,DB,244896,香港,500,半导体 D100,DB,543378,香港,100,永久 我的要求是用两个条件过滤记录 a) EmpId以“244”开头或EmpId以“543”开头 b) 空类型为“合同”和“永久”

我在下面试过了

 try (Stream<String> stream = Files.lines(Paths.get(fileAbsolutePath))) {
    list = stream                
        .filter(line -> line.contains("244") || line.contains("543"))
        .collect(Collectors.toList());
     }
try(Stream=Files.line(path.get(fileAbsolutePath))){
列表=流
.filter(line->line.contains(“244”)| | line.contains(“543”))
.collect(Collectors.toList());
}
它根据244和543筛选员工,但我担心的是,由于我使用的是contains,它可能还会获取其他数据,即它不仅会从EmpId列获取数据,还会从其他列获取数据(其他列也可能有以这些数字开头的数据)

类似地,当我逐行阅读时,要合并EmpType,我没有办法强制要求EmpType应为“永久”和“合同”


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

优雅的方式是正则表达式,我现在将跳过它。使用流API的不太优雅的方式如下:

list = stream.filter(line -> {
    String empId = line.split(",")[2];
    return empId.startsWith("244") || empId.startsWith("543");
}.collect(Collectors.toList());
使用流API的较短方法(由shmosel指出)是使用迷你正则表达式

list = stream.filter(line -> line.split(",")[2].matches("(244|543).*")
             .collect(Collectors.toList());
你可以这样做

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();
}
Pattern逗号=Pattern.compile(“,”);
Pattern empNum=Pattern.compile(“(244 | 543)\\d+”);
Pattern empType=Pattern.compile(“(合同|永久)”);
试试(Stream=Files.lines(path.get(“C:\\data\\sample.txt”)){
列表结果=stream.skip(2).map(l->comma.split(l))
.filter->empNum.matcher(s[2]).matches()
.filter->empType.matcher[5]).matches()
.map->Arrays.stream.collect(收集器.连接(“,”))
.collect(Collectors.toList());
系统输出打印项次(结果);
}捕获(IOE异常){
e、 printStackTrace();
}

首先读取文件并跳过两行标题。然后使用
字符将其拆分。使用
EmpId
EmpType
将其过滤掉。接下来,再次合并令牌以形成行,最后使用regex将每行收集到一个
列表中。否则,用
中断每个字符串(代表每行),然后使用索引2子字符串进行比较。或
行->行.split(,“”[2]。matches((244 | 543)。*”
@shmosel或
行->行.matches([^,]*,){2}(244 | 543)(,*)”)
完美。。谢谢:)