Skip to main content
added 202 characters in body
Source Link
Caleth
  • 12.4k
  • 2
  • 29
  • 45

A reason to prefer Streams over for is that for does everything. You get to use different names for different operations, rather than having to recognise a pattern spread across tens of lines.

The problem with both versions is doing everything in one method. You are missing functions like

Stream<T> <T> notNull(Stream<T> objects) { 
    return objects.filter(o -> o != null); 
}

Stream<Pair<Folder, Folder>> getFolderPairs(Project project) { 
    return project.getFolders().stream()
        .map(folder ->
            Pair.of(folder, project.getGeneratorSource())
        );
}

boolean isNotSourceFolder(Pair<Folder, Folder> folders) {
    return !folders.getLeft().equals(folders.getRight());
}

Stream<Folder> subfoldersFor(Stream<Project> projects) { 
    return notNull(projects)
        .flatMap(getFolderPairs)
        .filter(isNotSourceFolder)
        .map(Pair::getLeft)
}

boolean canGenerateImages(Folder folder) { 
    return (folder.getDerivative().isPresent() 
         || folder.getDpi().isPresent() 
         || folder.getImageScale().isPresent() 
         || folder.getImageSize().isPresent()) 
}

Note that I use sensible names for the parameters of my lambda expressions, rather than lambda everywhere.

Using those, your original function becomes much simpler, even with a formatter that wants things together.

return subfoldersFor(projects.parallelStream())
    .anyMatch(canGenerateImages);

The problem with both versions is doing everything in one method. You are missing functions like

Stream<T> <T> notNull(Stream<T> objects) { 
    return objects.filter(o -> o != null); 
}

Stream<Pair<Folder, Folder>> getFolderPairs(Project project) { 
    return project.getFolders().stream()
        .map(folder ->
            Pair.of(folder, project.getGeneratorSource())
        );
}

boolean isNotSourceFolder(Pair<Folder, Folder> folders) {
    return !folders.getLeft().equals(folders.getRight());
}

Stream<Folder> subfoldersFor(Stream<Project> projects) { 
    return notNull(projects)
        .flatMap(getFolderPairs)
        .filter(isNotSourceFolder)
        .map(Pair::getLeft)
}

boolean canGenerateImages(Folder folder) { 
    return (folder.getDerivative().isPresent() 
         || folder.getDpi().isPresent() 
         || folder.getImageScale().isPresent() 
         || folder.getImageSize().isPresent()) 
}

Note that I use sensible names for the parameters of my lambda expressions, rather than lambda everywhere.

Using those, your original function becomes much simpler, even with a formatter that wants things together.

return subfoldersFor(projects.parallelStream())
    .anyMatch(canGenerateImages);

A reason to prefer Streams over for is that for does everything. You get to use different names for different operations, rather than having to recognise a pattern spread across tens of lines.

The problem with both versions is doing everything in one method. You are missing functions like

Stream<T> <T> notNull(Stream<T> objects) { 
    return objects.filter(o -> o != null); 
}

Stream<Pair<Folder, Folder>> getFolderPairs(Project project) { 
    return project.getFolders().stream()
        .map(folder ->
            Pair.of(folder, project.getGeneratorSource())
        );
}

boolean isNotSourceFolder(Pair<Folder, Folder> folders) {
    return !folders.getLeft().equals(folders.getRight());
}

Stream<Folder> subfoldersFor(Stream<Project> projects) { 
    return notNull(projects)
        .flatMap(getFolderPairs)
        .filter(isNotSourceFolder)
        .map(Pair::getLeft)
}

boolean canGenerateImages(Folder folder) { 
    return (folder.getDerivative().isPresent() 
         || folder.getDpi().isPresent() 
         || folder.getImageScale().isPresent() 
         || folder.getImageSize().isPresent()) 
}

Note that I use sensible names for the parameters of my lambda expressions, rather than lambda everywhere.

Using those, your original function becomes much simpler, even with a formatter that wants things together.

return subfoldersFor(projects.parallelStream())
    .anyMatch(canGenerateImages);
Source Link
Caleth
  • 12.4k
  • 2
  • 29
  • 45

The problem with both versions is doing everything in one method. You are missing functions like

Stream<T> <T> notNull(Stream<T> objects) { 
    return objects.filter(o -> o != null); 
}

Stream<Pair<Folder, Folder>> getFolderPairs(Project project) { 
    return project.getFolders().stream()
        .map(folder ->
            Pair.of(folder, project.getGeneratorSource())
        );
}

boolean isNotSourceFolder(Pair<Folder, Folder> folders) {
    return !folders.getLeft().equals(folders.getRight());
}

Stream<Folder> subfoldersFor(Stream<Project> projects) { 
    return notNull(projects)
        .flatMap(getFolderPairs)
        .filter(isNotSourceFolder)
        .map(Pair::getLeft)
}

boolean canGenerateImages(Folder folder) { 
    return (folder.getDerivative().isPresent() 
         || folder.getDpi().isPresent() 
         || folder.getImageScale().isPresent() 
         || folder.getImageSize().isPresent()) 
}

Note that I use sensible names for the parameters of my lambda expressions, rather than lambda everywhere.

Using those, your original function becomes much simpler, even with a formatter that wants things together.

return subfoldersFor(projects.parallelStream())
    .anyMatch(canGenerateImages);