You might need to collect the List<FileInfo>
in to map and then convert that into List<List<FileInfo>>
. This can be achieved using the Collectors.collectingAndThen
, first you can apply Collectors.groupingBy
and then customer to convert the map to List<List<FileInfo>>
.
In the example below for grouping the file size is added and divided by the FILE_GROUP_LIMIT and quotient is used for gropuing.
Hope that helps.
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;
public class FileInfoProcessor {
private static Double FILE_GROUP_LIMIT = 200D;
public static void main(String[] args) throws Exception {
FileInfoProcessor processor = new FileInfoProcessor();
List<FileInfo> files = List.of(new FileInfo("A", 100l, "Active"),
new FileInfo("B", 100l, "Active"),
new FileInfo("C", 100l, "Active"),
new FileInfo("D", 100l, "Active"));
List<List<FileInfo>> finalList = processor.processFiles(files);
System.out.println(finalList);
}
private List<List<FileInfo>> processFiles(List<FileInfo> files) {
return files
.stream()
.collect(
Collectors.collectingAndThen(
Collectors.groupingBy(fileInfoFunction(), Collectors.toList()), // This will convert the List<FileInfo> to Map<String, List<FileInfo>>
map -> map.entrySet().stream().map(entry -> entry.getValue()).collect(Collectors.toList()))); // This will convert Map<String, List<FileInfo>> to List<List<FileInfo>>
}
private Function<FileInfo, String> fileInfoFunction() {
final AtomicLong fileSizeAccumulator = new AtomicLong(0l);
return (FileInfo file) -> {
return String.valueOf(Math.ceil((double)fileSizeAccumulator.addAndGet(file.fileSize) / FILE_GROUP_LIMIT)); // This will return the quotient by which the map can be created grouped.
};
}
static class FileInfo {
private String filePath;
private Long fileSize;
private String status;
public FileInfo(final String filePath, final Long fileSize, final String status) {
this.filePath = filePath;
this.fileSize = fileSize;
this.status = status;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(final String filePath) {
this.filePath = filePath;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(final Long fileSize) {
this.fileSize = fileSize;
}
public String getStatus() {
return status;
}
public void setStatus(final String status) {
this.status = status;
}
@Override
public String toString() {
return "FileInfo{" + "filePath='" + filePath + '\'' + ", fileSize=" + fileSize + ", status='"
+ status + '\'' + '}';
}
}
}