Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.moon.core.util.TableImpl Maven / Gradle / Ivy
package com.moon.core.util;
import com.moon.core.util.function.TableConsumer;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import static java.util.Collections.EMPTY_SET;
/**
* @author moonsky
*/
public class TableImpl implements Table {
protected transient Map> table;
protected transient Supplier>> containerCreator;
protected transient Function> rowCreator;
public TableImpl() { this(x -> new HashMap<>()); }
public TableImpl(Function> rowCreator) { this(HashMap::new, rowCreator); }
public TableImpl(Supplier>> containerCreator, Function> rowCreator) {
this.containerCreator = containerCreator;
this.rowCreator = rowCreator;
}
public static TableImpl newHashTable() { return new TableImpl<>(); }
public static TableImpl newLinkedHashTable() {
return new TableImpl<>(() -> new LinkedHashMap<>(), x -> new LinkedHashMap<>());
}
public static TableImpl newWeakHashTable() {
return new TableImpl<>(() -> new WeakHashMap<>(), x -> new WeakHashMap<>());
}
private Map ensureTable() {
Map> table = this.table;
if (table == null) {
table = containerCreator.get();
this.table = table;
}
return table;
}
private Map ensureRow(Object x) {
Map> table = this.ensureTable();
Map row = table.get(x);
if (row == null) {
row = rowCreator.apply(x);
table.put((X) x, row);
}
return row;
}
private Map nullableRow(Object x) {
Map> table = this.table;
return table == null ? null : table.get(x);
}
@Override
public Z put(X x, Y y, Z z) { return ensureRow(x).put(y, z); }
@Override
public Z putIfAbsent(X x, Y y, Z z) { return ensureRow(x).putIfAbsent(y, z); }
@Override
public Z get(Object x, Object y) {
Map row = nullableRow(x);
return row == null ? null : row.get(y);
}
@Override
public Map put(X x, Map extends Y, ? extends Z> map) {
Map> table = this.ensureTable();
return table.put(x, (Map) map);
}
@Override
public void putAll(X x, Map extends Y, ? extends Z> map) {
Map row = ensureRow(x);
row.putAll(map);
}
@Override
public Map get(Object x) { return nullableRow(x); }
@Override
public void putAll(Table extends X, ? extends Y, ? extends Z> table) {
if (table != null) {
X x;
Map row, inputRow;
Map> present = this.ensureTable();
for (Map.Entry extends X, ? extends Map extends Y, ? extends Z>> entry : table.rowsEntrySet()) {
inputRow = entry.getValue();
x = entry.getKey();
row = present.get(x);
if (row == null) {
if (inputRow == null) {
present.put(x, null);
} else {
row = rowCreator.apply(x);
row.putAll(inputRow);
present.put(x, row);
}
} else {
if (inputRow != null) {
row.putAll(inputRow);
}
}
}
}
}
@Override
public Z remove(Object x, Object y) {
Map row = nullableRow(x);
if (row == null) {
return null;
} else {
return row.remove(y);
}
}
@Override
public Map remove(Object x) { return table == null ? null : table.remove(x); }
@Override
public boolean containsValue(Object value) {
Map> table = this.table;
if (table == null) {
return false;
} else {
for (Map.Entry> xMapEntry : table.entrySet()) {
Map row = xMapEntry.getValue();
if (row.containsValue(value)) {
return true;
}
}
}
return false;
}
@Override
public Set keys() { return table == null ? EMPTY_SET : table.keySet(); }
@Override
public Collection> rows() { return table == null ? EMPTY_SET : table.values(); }
@Override
public Set>> rowsEntrySet() { return table == null ? EMPTY_SET : table.entrySet(); }
@Override
public void forEach(TableConsumer consumer) {
Set>> entries = rowsEntrySet();
for (Map.Entry> entry : entries) {
Map row = entry.getValue();
X x = entry.getKey();
if (row != null) {
row.forEach((key, value) -> consumer.accept(x, key, value));
}
}
}
@Override
public void clear() { this.table = null; }
@Override
public int sizeOfRows() { return table == null ? 0 : table.size(); }
@Override
public int maxSizeOfColumns() { return obtainSize(0, Math::max); }
@Override
public int minSizeOfColumns() { return obtainSize(Integer.MAX_VALUE, Math::min); }
@Override
public int size() { return obtainSize(0, TableImpl::sum); }
public TableImpl sandbox(
Function> rowCreator,
Consumer super TableImpl extends X, ? extends Y, ? extends Z>> consumer
) {
Function supplier = this.rowCreator;
this.rowCreator = rowCreator;
consumer.accept(this);
this.rowCreator = supplier;
return this;
}
private int obtainSize(int initialize, IntCalculator calculator) {
Map> table = this.table;
if (table == null || table.isEmpty()) {
return 0;
} else {
int size = initialize;
for (Map.Entry> xMapEntry : table.entrySet()) {
Map row = xMapEntry.getValue();
if (row != null && !row.isEmpty()) {
size = calculator.calc(size, row.size());
}
}
return size;
}
}
private static int sum(int v1, int v2) { return v1 + v2; }
interface IntCalculator {
int calc(int prev, int size);
}
}