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 se.ugli.habanero.j.util.Option;
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);
}
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;
}
public final Iterable group(final GroupContext cxt, final GroupFunction group) {
return group.createObjects(cxt.tuples);
}
protected abstract Option createObject(GroupContext cxt, TypedMap typedMap);
final Iterable createObjects(final Iterable tuples) {
final List result = new ArrayList();
final Map> index = createIndex(tuples);
for (final TypedMap groupedTypedMap : index.keySet())
addCreatedObject(result, groupedTypedMap, new GroupContext(index.get(groupedTypedMap)));
return result;
}
private final Map> createIndex(final Iterable tuples) {
final Map> result = new LinkedHashMap>();
for (final TypedMap tuple : tuples)
addTuple(result, tuple);
return result;
}
private void addTuple(final Map> result, final TypedMap tuple) {
final TypedHashMap groupedTypeMap = createGroupedTypedMap(tuple);
if (!result.containsKey(groupedTypeMap))
result.put(groupedTypeMap, new ArrayList());
result.get(groupedTypeMap).add(tuple);
}
private TypedHashMap createGroupedTypedMap(final TypedMap tuple) {
final TypedHashMap result = new TypedHashMap();
for (final String column : columns)
result.map.put(column, tuple.get(column));
return result;
}
private void addCreatedObject(final List result, final TypedMap groupedTypedMap, final GroupContext cxt) {
final Option opt = createObject(cxt, groupedTypedMap);
if (opt.isDefined())
result.add(opt.get());
}
}