1

I am trying to convert the below traditional for loop in Java 8. I tried iterating over the loop using stream's forEach and used a filter for contains check but I am unable to understand how to make a call to extractForDate() method and return the value. Please can you assist with the approach?

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;
            }
        }

Below is the method implementation.

    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;
    }
nilFi
  • 197
  • 2
  • 18
  • the code looks fine ..have tried and checked whether the code inside the if condition is getting executed or not ??.....u can add a print statement to check that – Daksh Rawal Apr 13 '22 at 11:55
  • @daksh, yes it does work with the above approach I am just trying to understand how the traditional for loop above can be converted using Lamba\stream api. – nilFi Apr 13 '22 at 12:04
  • 1
    check this ..https://stackoverflow.com/a/43819804/15597511 – Daksh Rawal Apr 13 '22 at 12:10
  • 2
    Please don't use `Date` or `SimpleDateFormat`, as they are obsolete. Instead, use classes from the `java.time` package. – MC Emperor Apr 13 '22 at 14:17

3 Answers3

3

To use Lambda/Stream api you need to have a List instance, you can convert your lines to ArrayList and do the 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());
    }
});
I'm Weverton
  • 562
  • 4
  • 5
2

If I understood your code correctly you only want to create a date for the first line matching your expression. For that you can use filter() and findFirst(), which will give you an Optional on which you can use map() to create your date if anyone was found. I separated each step in its own map function but you can of course merge them into one.

    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);
Johannes
  • 146
  • 1
  • 5
1

It doesn't stray that much from what you already have. You just need to break each step (filtering, mapping, collecting results) to a stream function. This is what you're looking for:

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

Here there's also a Test class where I assumed your regex and array of lines

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;
    }
}
Dan
  • 3,647
  • 5
  • 20
  • 26