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