使用 Java 8 Lambda \ Stream 从循环调用方法并返回值

Calling method from loop and returning value using Java 8 Lambda \ Stream

我正在尝试在 Java 8 中转换下面的传统 for 循环。我尝试使用流的 forEach 迭代循环并使用过滤器 contains 检查但是我无法理解如何调用 extractForDate() 方法和 return 值。请问你能协助解决这个问题吗?

for (int i = 0; i < lines.length; i++) {
            if (lines[i].contains(FOR_DATE)) {
                String regex = "regex expression";
                forDate = extractForDate(lines[i], regex);
                java.sql.Date sd = new java.sql.Date(forDate.getTime())
                break;
            }
        }

下面是方法实现。

    private static Date extractForDate(String Line, string regex) {
        Matcher m = Pattern.compile(regex).matcher(line);
        Date startDate = null,
        if (m.find()) {
            try {
                startDate = new SimpleDateFormat("Mddyyyy").parse(m.group(1));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return startDate;
    }

要使用 Lambda/Stream api 您需要有一个 List 实例,您可以将行转换为 ArrayList 并执行 foreach:

//...    
List<String> linesList = new ArrayList<>(lines);

linesList.stream()
    .filter(line -> line.contains(FOR_DATE)) //filter lines which contains FOR_DATE
    .map(line -> extractForDate(line, "regex")) //returns a list of Date e.g. List<Date>
    .forEach(date -> {
        java.sql.Date sd = new java.sql.Date(forDate.getTime());
    }
});

它不会偏离您已有的东西那么多。您只需要将每个步骤(过滤、映射、收集结果)分解为一个流函数。这就是您要查找的内容:

List<Date> listDates = Arrays.stream(lines)
    .filter(line -> line.contains(FOR_DATE))
    .map(line -> extractForDate(line, regex))
    .collect(Collectors.toList());

这里还有一个测试 class,我假设你的正则表达式和行数组

public class Test {
    public static final String FOR_DATE = "DATE:";

    public static void main(String[] args) throws ParseException {
        String[] lines = new String[]{"DATE: 2152022", "test", "160220", "DATE: 1012001"};
        String regex = "(\d\d{2}\d{4})";

        List<Date> listDates = Arrays.stream(lines)
                .filter(line -> line.contains(FOR_DATE))
                .map(line -> extractForDate(line, regex))
                .collect(Collectors.toList());

        for (Date d : listDates) {
            System.out.println(d);
        }
    }

    private static Date extractForDate(String line, String regex) {
        Matcher m = Pattern.compile(regex).matcher(line);
        Date startDate = null;
        if (m.find()) {
            try {
                startDate = new SimpleDateFormat("Mddyyyy").parse(m.group(1));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return startDate;
    }
}

如果我正确理解了您的代码,您只想为匹配您的表达式的第一行创建一个日期。为此,您可以使用 filter() 和 findFirst(),这将为您提供一个 Optional,如果找到任何人,您可以在该 Optional 上使用 map() 创建您的日期。我在自己的地图函数中将每个步骤分开,但您当然可以将它们合并为一个。

    java.sql.Date date = Arrays.stream(lines)
            .filter(line -> line.contains(FOR_DATE))
            .findFirst()
            .map(line -> extractForDate(line, "regex expression"))
            .map(Date::getTime)
            .map(java.sql.Date::new)
            .orElse(null);