com.xlrit.gears.base.util.ExtraCollectors Maven / Gradle / Ivy
package com.xlrit.gears.base.util;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import com.xlrit.gears.base.function.Operators;
import lombok.Getter;
import org.checkerframework.checker.nullness.qual.Nullable;
import static java.util.stream.Collector.Characteristics.*;
public class ExtraCollectors {
private ExtraCollectors() {}
public static Collector, T> first() {
return createSingleElementCollector(Operators::first);
}
public static Collector, T> last() {
return createSingleElementCollector(Operators::last);
}
public static Collector, T> only() {
return createSingleElementCollector(Operators::only);
}
private static Collector, T> createSingleElementCollector(Function, T> fun) {
return Collector.of(
ArrayList::new,
ArrayList::add,
(left, right) -> {
left.addAll(right);
return left;
},
fun,
UNORDERED
);
}
public static Collector, Long> sumLong() {
return createSummingCollector(LongSummer::new);
}
public static Collector, BigDecimal> sumDecimal() {
return createSummingCollector(BigDecimalSummer::new);
}
private static Collector,T> createSummingCollector(Supplier> supplier) {
return Collector.of(
supplier,
Summer::add,
Summer::combine,
Summer::getValue,
CONCURRENT, UNORDERED
);
}
public interface Summer {
void add(T value);
default Summer combine(Summer other) {
this.add(other.getValue());
return this;
}
T getValue();
}
@Getter
static class LongSummer implements Summer {
private Long value;
public LongSummer() {
this.value = 0L;
}
@Override
public void add(Long value) {
if (this.value == null) return;
if (value == null) this.value = null;
else this.value += value;
}
}
@Getter
static class BigDecimalSummer implements Summer {
private BigDecimal value;
public BigDecimalSummer() {
this.value = BigDecimal.ZERO;
}
public void add(BigDecimal value) {
if (this.value == null) return;
if (value == null) this.value = null;
else this.value = this.value.add(value);
}
}
}