All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.map.multi.RowKeyTable Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.core.map.multi;

import cn.hutool.core.builder.Builder;
import cn.hutool.core.collection.ComputeIter;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.collection.TransIter;
import cn.hutool.core.map.AbsEntry;
import cn.hutool.core.map.MapUtil;

import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 将行的键作为主键的{@link Table}实现
* 此结构为: 行=(列=值) * * @param 行类型 * @param 列类型 * @param 值类型 * @author Guava, Looly * @since 5.7.23 */ public class RowKeyTable extends AbsTable { final Map> raw; /** * 列的Map创建器,用于定义Table中Value对应Map类型 */ final Builder> columnBuilder; //region 构造 /** * 构造 */ public RowKeyTable() { this(new HashMap<>()); } /** * 构造 * * @param isLinked 是否有序,有序则使用{@link java.util.LinkedHashMap}作为原始Map * @since 5.8.0 */ public RowKeyTable(boolean isLinked) { this(MapUtil.newHashMap(isLinked), () -> MapUtil.newHashMap(isLinked)); } /** * 构造 * * @param raw 原始Map */ public RowKeyTable(Map> raw) { this(raw, HashMap::new); } /** * 构造 * * @param raw 原始Map * @param columnMapBuilder 列的map创建器 */ public RowKeyTable(Map> raw, Builder> columnMapBuilder) { this.raw = raw; this.columnBuilder = null == columnMapBuilder ? HashMap::new : columnMapBuilder; } //endregion @Override public Map> rowMap() { return raw; } @Override public V put(R rowKey, C columnKey, V value) { return raw.computeIfAbsent(rowKey, (key) -> columnBuilder.build()).put(columnKey, value); } @Override public V remove(R rowKey, C columnKey) { final Map map = getRow(rowKey); if (null == map) { return null; } final V value = map.remove(columnKey); if (map.isEmpty()) { raw.remove(rowKey); } return value; } @Override public boolean isEmpty() { return raw.isEmpty(); } @Override public void clear() { this.raw.clear(); } @Override public boolean containsColumn(C columnKey) { if (columnKey == null) { return false; } for (Map map : raw.values()) { if (null != map && map.containsKey(columnKey)) { return true; } } return false; } //region columnMap @Override public Map> columnMap() { Map> result = columnMap; return (result == null) ? columnMap = new ColumnMap() : result; } private Map> columnMap; private class ColumnMap extends AbstractMap> { @Override public Set>> entrySet() { return new ColumnMapEntrySet(); } } private class ColumnMapEntrySet extends AbstractSet>> { private final Set columnKeySet = columnKeySet(); @Override public Iterator>> iterator() { return new TransIter<>(columnKeySet.iterator(), c -> MapUtil.entry(c, getColumn(c))); } @Override public int size() { return columnKeySet.size(); } } //endregion //region columnKeySet @Override public Set columnKeySet() { Set result = columnKeySet; return (result == null) ? columnKeySet = new ColumnKeySet() : result; } private Set columnKeySet; private class ColumnKeySet extends AbstractSet { @Override public Iterator iterator() { return new ColumnKeyIterator(); } @Override public int size() { return IterUtil.size(iterator()); } } private class ColumnKeyIterator extends ComputeIter { final Map seen = columnBuilder.build(); final Iterator> mapIterator = raw.values().iterator(); Iterator> entryIterator = IterUtil.empty(); @Override protected C computeNext() { while (true) { if (entryIterator.hasNext()) { Map.Entry entry = entryIterator.next(); if (false == seen.containsKey(entry.getKey())) { seen.put(entry.getKey(), entry.getValue()); return entry.getKey(); } } else if (mapIterator.hasNext()) { entryIterator = mapIterator.next().entrySet().iterator(); } else { return null; } } } } //endregion //region getColumn @Override public List columnKeys() { final Collection> values = this.raw.values(); final List result = new ArrayList<>(values.size() * 16); for (Map map : values) { map.forEach((key, value)->{result.add(key);}); } return result; } @Override public Map getColumn(C columnKey) { return new Column(columnKey); } private class Column extends AbstractMap { final C columnKey; Column(C columnKey) { this.columnKey = columnKey; } @Override public Set> entrySet() { return new EntrySet(); } private class EntrySet extends AbstractSet> { @Override public Iterator> iterator() { return new EntrySetIterator(); } @Override public int size() { int size = 0; for (Map map : raw.values()) { if (map.containsKey(columnKey)) { size++; } } return size; } } private class EntrySetIterator extends ComputeIter> { final Iterator>> iterator = raw.entrySet().iterator(); @Override protected Entry computeNext() { while (iterator.hasNext()) { final Entry> entry = iterator.next(); if (entry.getValue().containsKey(columnKey)) { return new AbsEntry() { @Override public R getKey() { return entry.getKey(); } @Override public V getValue() { return entry.getValue().get(columnKey); } @Override public V setValue(V value) { return entry.getValue().put(columnKey, value); } }; } } return null; } } } //endregion }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy