Skip to content

Instantly share code, notes, and snippets.

@ansell
Last active August 29, 2015 14:04
Show Gist options
  • Save ansell/fa10da6a4aa887c475ae to your computer and use it in GitHub Desktop.
Save ansell/fa10da6a4aa887c475ae to your computer and use it in GitHub Desktop.
Aggregation of CSV rows using Java-8 functions
/**
* Finds a unique result in the given file, based on examining rows from the CSV and comparing
* them sequentially down the file using the given value aggregator function.
*
* @param <T>
* The type of the value that is being compared.
* @param <R>
* The type of the value that is being returned as the aggregation.
* @param nextFile
* The file to check
* @param valueAggregator
* A {@link BiFunction} which compares values and returns another value based on the
* initial value and the value for the current row in the CSV. The initial value must
* be explicitly allowed for as the first case.
* @param initialResultValue
* The initial result value to use, and the default to return, if the file is empty.
* @param valueFromHeadersAndLine
* A {@link BiFunction} which takes a List of Strings as the headers, and a line
* afterwards and returns the desired value for comparison for that line.
* @return A value aggregated across the entire file, based on sequential processing of each of
* the lines, without holding the entire file in memory at any time.
* @throws IOException
* If there is an exception handling the csv file
*/
public static <T, R> R aggregateRows(final Path nextFile, final BiFunction<R, T, R> valueAggregator,
final BiFunction<List<String>, String[], T> valueFromHeadersAndLine, final R initialResultValue)
throws IOException
{
R result = initialResultValue;
try (final CSVReader reader = new CSVReader(Files.newBufferedReader(nextFile, StandardCharsets.UTF_8));)
{
List<String> headers = null;
String[] nextLine;
while((nextLine = reader.readNext()) != null)
{
if(headers == null)
{
// header line is mandatory at this point as the first line
headers = Arrays.asList(nextLine);
}
else
{
final T nextValue = valueFromHeadersAndLine.apply(headers, nextLine);
// NOTE: The initialResultValue, if mutable, may be modified in the method, and
// the same reference returned as the result
result = valueAggregator.apply(result, nextValue);
}
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment