javastreamjava-streamwriter

Write String values in Writer object with Java 8 Stream


I'm trying to replace an ordinary for loop which writes String values in a Writer object with stream in the following code:

public void save() {
    try (Writer fileWriter = new FileWriter(file)) {
        fileWriter.write("someStrings\n");

        ArrayList<ParentType> parentList = super.getParentType();
        for (ParentType parentTypeObj : parentList) {
            fileWriter.write(toString(parentTypeObj) + "\n");
        }

        ArrayList<ChildType> childList = super.getChildType();
        for (ChildType childTypeObj : childList) {
            fileWriter.write(toString(childTypeObj) + "\n");
        }

    } catch (IOException e) {
        throw new ManagerSaveException();
    }
}

public static String toString(ParentType parentTypeObj) {
    if (parentTypeObj == null) return null;
    String result = "";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy, HH:mm");
    if (parentTypeObj instanceof ChildType) {
        String startTime = parentTypeObj.getStartTime().format(formatter);
        String endTime = parentTypeObj.getEndTime().format(formatter);
        result = Integer.toString(parentTypeObj.getIdNum()) + ","
                + parentTypeObj.getClass().getSimpleName().toUpperCase() + ","
                + parentTypeObj.getName() + ","
                + parentTypeObj.getStatus() + ","
                + parentTypeObj.getDescription() + ","
                + ((ChildType) parentTypeObj).getSpecId() + ","
                + parentTypeObj.getDuration().toMinutes() + ","
                + startTime + ","
                + endTime + ",";
    } else {
        String startTime = parentTypeObj.getStartTime().format(formatter);
        String endTime = parentTypeObj.getEndTime().format(formatter);
        result = Integer.toString(parentTypeObj.getIdNum()) + ","
                + parentTypeObj.getClass().getSimpleName().toUpperCase() + ","
                + parentTypeObj.getName() + ","
                + parentTypeObj.getStatus() + ","
                + parentTypeObj.getDescription() + ","
                + parentTypeObj.getDuration().toMinutes() + ","
                + startTime + ","
                + endTime + ",";
    }
    return result;
}

How to do it?

Expected to write String values in a Writer object via Stream.


Solution

  • Basically that should looks like (same for childList):

    ArrayList<ParentType> parentList = super.getParentType();
    parentList.stream()             // Stream<ParentType>
        .map(p -> toString(p)+"\n") // Stream<String>
        .forEach(fileWriter::write);
    

    Alas, write method may throw an exception, and this is forbidden with the Stream API. You then have to, either:

        .forEach(s -> {
            try {
                fileWrite.write(s);
            } catch(Exception e) {
                // internally catched
            }
        })
    
        .forEach(s -> {
            try {
                fileWrite.write(s);
            } catch(Exception e) {
                throw new UncheckedIOException("Bang!",e); // so that it can be catched outside the Stream by chaining it to a RuntimeException.
            }
        })
    

    ---EDIT---

    Same reasoning must be applied to the method toString if it throws something...