se.ugli.habanero.j.GroupFunction Maven / Gradle / Ivy
package se.ugli.habanero.j;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public abstract class GroupFunction {
public static class GroupContext {
private final Iterable tuples;
private GroupContext(final Iterable tuples) {
this.tuples = tuples;
}
}
private final Iterable columns;
public GroupFunction(final String column1, final String... columns) {
this.columns = createColumnIterable(column1, columns);
}
public final Iterable group(final GroupContext cxt, final GroupFunction group) {
return group.createObjects(cxt.tuples);
}
final Iterable createObjects(final Iterable tuples) {
final List result = new ArrayList();
final Map> index = createIndex(tuples);
for (final String groupedKey : index.keySet()) {
final List groupedTuples = index.get(groupedKey);
final TypedMap firstTuple = groupedTuples.get(0);
addCreatedObject(result, firstTuple, new GroupContext(groupedTuples));
}
return result;
}
protected abstract Optional createObject(GroupContext cxt, TypedMap typedMap);
private void addCreatedObject(final List result, final TypedMap typeMap, final GroupContext cxt) {
final Optional opt = createObject(cxt, typeMap);
if (opt.isPresent())
result.add(opt.get());
}
private void addTuple(final Map> result, final TypedMap tuple) {
final String groupedTypeMap = createGroupKey(tuple);
if (!result.containsKey(groupedTypeMap))
result.put(groupedTypeMap, new ArrayList());
result.get(groupedTypeMap).add(tuple);
}
private Iterable createColumnIterable(final String column1, final String... columns) {
final List result = new ArrayList();
result.add(column1);
for (final String column : columns)
result.add(column);
return result;
}
private String createGroupKey(final TypedMap tuple) {
final StringBuilder result = new StringBuilder();
for (final String column : columns) {
result.append(column);
final Object value = tuple.get(column);
result.append(value);
}
return result.toString();
}
private final Map> createIndex(final Iterable tuples) {
final Map> result = new LinkedHashMap>();
for (final TypedMap tuple : tuples)
addTuple(result, tuple);
return result;
}
}