com.github.paganini2008.devtools.beans.streaming.Groups Maven / Gradle / Ivy
package com.github.paganini2008.devtools.beans.streaming;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import com.github.paganini2008.devtools.jdbc.ResultSetSlice;
/**
*
* Groups
*
* @author Fred Feng
*
*
* @version 1.0
*/
public class Groups implements Groupable {
private List> groups = new ArrayList>();
Groups(List elements) {
groups.add(new GroupImpl(new LinkedHashMap<>(), elements, null));
}
public Groupable having(Predicate> predicate) {
groups = groups.stream().filter(predicate).collect(Collectors.toList());
return this;
}
public Groupable orderBy(Sort> sort) {
this.groups.sort(sort);
return this;
}
public Groupable groupBy(Function function, String attributeName) {
List> updated = new ArrayList>();
for (Group group : new ArrayList>(groups)) {
updated.addAll(divide(group, function, attributeName));
}
groups.clear();
groups.addAll(updated);
return this;
}
public ResultSetSlice setTransformer(Transformer, T> transformer) {
return new MemoryResultSetSlice<>(groups, transformer);
}
private List> divide(Group group, Function function, String attributeName) {
List> groups = new ArrayList>();
Map> data = group.elements().stream().collect(Collectors.groupingBy(function, Collectors.toList()));
for (Map.Entry> entry : data.entrySet()) {
Map attributes = new LinkedHashMap(group.getAttributes());
attributes.put(attributeName, entry.getKey());
groups.add(new GroupImpl(attributes, entry.getValue(), group));
}
return groups;
}
/**
*
* GroupImpl
*
* @author Fred Feng
*
* @version 1.0
*/
static class GroupImpl implements Group, Serializable {
private static final long serialVersionUID = -5752728250597378290L;
private final Map attributes;
private final List elements;
private final Group rollup;
GroupImpl(Map attributes, List elements, Group rollup) {
this.attributes = attributes;
this.elements = elements;
this.rollup = rollup;
}
public T summarize(Calculation calculation) {
return calculation.getResult(elements);
}
public Map getAttributes() {
return attributes;
}
public List elements() {
return elements;
}
public Group rollup() {
return rollup;
}
}
}