package xyz.zhouxy.plusone.commons.collection; import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.Objects; import java.util.Set; import javax.annotation.concurrent.ThreadSafe; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; /** * 将 {@link Table} 包装为同步集合,线程安全。 * *

* 可通过以下方式构建一个线程安全的 {@link Table} *

* *
 * SynchronizedTable.of(HashBasedTable.create())
 * 
* *

* NOTE: 如果 {@link Table} 不需要更改,请使用 {@link ImmutableTable} *

* * @author ZhouXY * @since 0.1.0-SNAPSHOT * @see Table * @see ImmutableTable */ @Beta @ThreadSafe public class SynchronizedTable implements Table, Serializable { private static final long serialVersionUID = 3716653837549439569L; @SuppressWarnings("serial") private final Table table; @SuppressWarnings("serial") private final Object mutex; private SynchronizedTable(Table table) { this.table = Objects.requireNonNull(table); this.mutex = this; } private SynchronizedTable(Table table, Object mutex) { this.table = Objects.requireNonNull(table); this.mutex = mutex; } public static SynchronizedTable of(Table table) { if (table instanceof SynchronizedTable) { return (SynchronizedTable) table; } else { return new SynchronizedTable<>(table); } } public static SynchronizedTable of(Table table, Object mutex) { if (table instanceof SynchronizedTable) { SynchronizedTable srcTable = (SynchronizedTable) table; return new SynchronizedTable<>(srcTable.table, mutex); } else { return new SynchronizedTable<>(table); } } @Override public boolean contains(Object rowKey, Object columnKey) { synchronized (mutex) { return this.table.contains(rowKey, columnKey); } } @Override public boolean containsRow(Object rowKey) { synchronized (mutex) { return this.table.containsRow(rowKey); } } @Override public boolean containsColumn(Object columnKey) { synchronized (mutex) { return this.table.containsColumn(columnKey); } } @Override public boolean containsValue(Object value) { synchronized (mutex) { return this.table.containsValue(value); } } @Override public V get(Object rowKey, Object columnKey) { synchronized (mutex) { return this.table.get(rowKey, columnKey); } } @Override public boolean isEmpty() { synchronized (mutex) { return this.table.isEmpty(); } } @Override public int size() { synchronized (mutex) { return this.table.size(); } } @Override public void clear() { synchronized (mutex) { this.table.clear(); } } @Override public V put(R rowKey, C columnKey, V value) { synchronized (mutex) { return this.table.put(rowKey, columnKey, value); } } @Override public void putAll(Table table) { synchronized (mutex) { this.table.putAll(table); } } @Override public V remove(Object rowKey, Object columnKey) { synchronized (mutex) { return this.table.remove(rowKey, columnKey); } } @Override public Map row(R rowKey) { synchronized (mutex) { return this.table.row(rowKey); } } @Override public Map column(C columnKey) { synchronized (mutex) { return this.table.column(columnKey); } } @Override public Set> cellSet() { synchronized (mutex) { return this.table.cellSet(); } } @Override public Set rowKeySet() { synchronized (mutex) { return this.table.rowKeySet(); } } @Override public Set columnKeySet() { synchronized (mutex) { return this.table.columnKeySet(); } } @Override public Collection values() { synchronized (mutex) { return this.table.values(); } } @Override public Map> rowMap() { synchronized (mutex) { return this.table.rowMap(); } } @Override public Map> columnMap() { synchronized (mutex) { return this.table.columnMap(); } } }