Java 8流多个过滤器

时间:2018-07-10 01:00:25

标签: java filter java-stream

我是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

我的要求是使用两个条件过滤记录 a)EmpId以“ 244”开头或EmpId以“ 543”开头 b)EmpType是“合同”和“永久”

我在下面尝试过

 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应该位于“永久”和“合同”中

我缺少任何高级选项吗?

2 个答案:

答案 0 :(得分:1)

一种优雅的方式是正则表达式,我现在将略过。使用Stream API的不太优雅的方法如下:

list = stream.filter(line -> {
    String empId = line.split(",")[2];
    return empId.startsWith("244") || empId.startsWith("543");
}.collect(Collectors.toList());

使用Stream API(由shmosel指出)的较短方法是使用迷你正则表达式。

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

答案 1 :(得分:1)

您可以这样做

    Dim strQuery As String = "SELECT CONVERT(DATE, CHECKIN) FROM VW_CHECKPOINT2 WHERE CHECKIN = @p1"
    Dim dt As DateTime = DateTime.ParseExact(CHECKIN, "MM/dd/yyyy", CultureInfo.InvariantCulture)
    Dim reformatted As String = dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)

首先读取文件,然后跳过2个标题行。然后使用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(); } 字符将其拆分。使用,EmpId过滤掉它。接下来,再次合并令牌以形成行,最后将每行收集到EmpType中。