cn.hutool.core.map.BiMap Maven / Gradle / Ivy
package cn.hutool.core.map;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* 双向Map
* 互换键值对不检查值是否有重复,如果有则后加入的元素替换先加入的元素
* 值的顺序在HashMap中不确定,所以谁覆盖谁也不确定,在有序的Map中按照先后顺序覆盖,保留最后的值
* 它与TableMap的区别是,BiMap维护两个Map实现高效的正向和反向查找
*
* @param 键类型
* @param 值类型
* @since 5.2.6
*/
public class BiMap extends MapWrapper {
private static final long serialVersionUID = 1L;
private Map inverse;
/**
* 构造
*
* @param raw 被包装的Map
*/
public BiMap(Map raw) {
super(raw);
}
@Override
public V put(K key, V value) {
final V oldValue = super.put(key, value);
if (null != this.inverse) {
if(null != oldValue){
// issue#I88R5M
// 如果put的key相同,value不同,需要在inverse中移除旧的关联
this.inverse.remove(oldValue);
}
this.inverse.put(value, key);
}
return super.put(key, value);
}
@Override
public void putAll(Map extends K, ? extends V> m) {
super.putAll(m);
if (null != this.inverse) {
m.forEach((key, value) -> this.inverse.put(value, key));
}
}
@Override
public V remove(Object key) {
final V v = super.remove(key);
if (null != this.inverse && null != v) {
this.inverse.remove(v);
}
return v;
}
@Override
public boolean remove(Object key, Object value) {
return super.remove(key, value) && null != this.inverse && this.inverse.remove(value, key);
}
@Override
public void clear() {
super.clear();
this.inverse = null;
}
/**
* 获取反向Map
*
* @return 反向Map
*/
public Map getInverse() {
if (null == this.inverse) {
inverse = MapUtil.inverse(getRaw());
}
return this.inverse;
}
/**
* 根据值获得键
*
* @param value 值
* @return 键
*/
public K getKey(V value) {
return getInverse().get(value);
}
@Override
public V putIfAbsent(K key, V value) {
if (null != this.inverse) {
this.inverse.putIfAbsent(value, key);
}
return super.putIfAbsent(key, value);
}
@Override
public V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction) {
final V result = super.computeIfAbsent(key, mappingFunction);
resetInverseMap();
return result;
}
@Override
public V computeIfPresent(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) {
final V result = super.computeIfPresent(key, remappingFunction);
resetInverseMap();
return result;
}
@Override
public V compute(K key, BiFunction super K, ? super V, ? extends V> remappingFunction) {
final V result = super.compute(key, remappingFunction);
resetInverseMap();
return result;
}
@Override
public V merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction) {
final V result = super.merge(key, value, remappingFunction);
resetInverseMap();
return result;
}
/**
* 重置反转的Map,如果反转map为空,则不操作。
*/
private void resetInverseMap() {
if (null != this.inverse) {
inverse = null;
}
}
}