Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在树映射中搜索(Java)_Java_Treemap - Fatal编程技术网

在树映射中搜索(Java)

在树映射中搜索(Java),java,treemap,Java,Treemap,我需要在地图地图中搜索并返回该元素所属的键。 我觉得这个实现很慢,你能帮我优化一下吗?。 我需要使用TreeSet,不能使用contains,因为它们使用compareTo,而equals/compareTo对是以不兼容的方式实现的,我无法更改。 (对不起,我的英语不好) Map m=new TreeSet(); 公共字符串getKeys(元素){ 对于(条目e:m.entrySet()){ mapSubKey=e.getValue(); 对于(条目e2:mapSubKey.entrySet()

我需要在地图地图中搜索并返回该元素所属的键。 我觉得这个实现很慢,你能帮我优化一下吗?。 我需要使用TreeSet,不能使用contains,因为它们使用compareTo,而equals/compareTo对是以不兼容的方式实现的,我无法更改。 (对不起,我的英语不好)

Map m=new TreeSet();
公共字符串getKeys(元素){
对于(条目e:m.entrySet()){
mapSubKey=e.getValue();
对于(条目e2:mapSubKey.entrySet()){
setElements=e2.getValue();
用于(元素元素:集合元素)
if(elem.equals(element))返回“Key:+e.getKey()+”子键:+e2.getKey();
}
}
}

如果您无法使用
contains
,并且无法使用地图地图,那么您唯一的实际选择就是像现在这样进行迭代

或者,您可以在单独的映射中保留
元素
键/子键
的反向映射,这将加快反向查找

此外,如果您不确定给定的
元素
只能存在于一个位置,您可能希望存储和检索
列表
,而不仅仅是
元素
,并在以相互兼容的方式实现时正确使用和工作。此外,在映射中搜索时,只有对键的搜索是有效的(对于树映射O(logn))。在地图中搜索值时,复杂性将变为线性


不过,在为元素类型实现自己的搜索时,有一种方法可以优化内部搜索。通过这种方式,您可以实现自己的compareTo方法,而无需更改元素对象本身。

这里的问题是键和值是向后的

映射允许有效地查找与键(
元素
,在本例中)关联的值(即
子键

倒退是缓慢的


有一些双向地图实现,比如支持双向更快访问的Google Collections,但这意味着要替换
TreeMap
。否则,维护两个贴图,每个方向一个。

这里是一个双向树贴图(或树贴图上的双射)

它将两个绑定在一起的重载树映射关联起来

每个“反向”常量字段都指向另一个树状图。一个树形图上的任何更改都会自动反映在其逆树形图上

因此,每个值都是唯一的

public class BiTreeMap<K, V> extends TreeMap<K, V> {
    public final BiTreeMap<V, K> inverse;

    private BiTreeMap(BiTreeMap inverse) {
        this.inverse = inverse;
    }

    public BiTreeMap() {
        inverse = new BiTreeMap<V, K>(this);
    }

    public BiTreeMap(Map<? extends K, ? extends V> m) {
        inverse = new BiTreeMap<V, K>(this);
        putAll(m);
    }

    public BiTreeMap(Comparator<? super K> comparator) {
        super(comparator);
        inverse = new BiTreeMap<V, K>(this);
    }

    public BiTreeMap(Comparator<? super K> comparatorK, Comparator<? super V> comparatorV) {
        super(comparatorK);
        inverse = new BiTreeMap<V, K>(this, comparatorV);
    }

    private BiTreeMap(BiTreeMap<V, K> inverse, Comparator<? super K> comparatorK) {
        super(comparatorK);
        this.inverse = inverse;
    }

    @Override
    public V put(K key, V value) {
        if(key == null || value == null) {
            throw new NullPointerException();
        }
        V oldValue = super.put(key, value);
        if (oldValue != null && inverse._compareKeys(value, oldValue) != 0) {
            inverse._remove(oldValue);
        }
        K inverseOldKey = inverse._put(value, key);
        if (inverseOldKey != null && _compareKeys(key, inverseOldKey) != 0) {
            super.remove(inverseOldKey);
        }
        return oldValue;
    }

    private int _compareKeys(K k1, K k2) {
        Comparator<? super K> c = comparator();
        if (c == null) {
            Comparable<? super K> ck1 = (Comparable<? super K>) k1;
            return ck1.compareTo(k2);
        } else {
            return c.compare(k1, k2);
        }
    }

    private V _put(K key, V value) {
        return super.put(key, value);
    }

    @Override
    public V remove(Object key) {
        V value = super.remove(key);
        inverse._remove(value);
        return value;
    }

    private V _remove(Object key) {
        return super.remove(key);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        for (Map.Entry<? extends K, ? extends V> e : map.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            put(key, value);
        }
    }

    @Override
    public void clear() {
        super.clear();
        inverse._clear();
    }

    private void _clear() {
        super.clear();
    }

    public boolean containsValue(Object value) {
        return inverse.containsKey(value);
    }

    @Override
    public Map.Entry<K, V> pollFirstEntry() {
        Map.Entry<K, V> entry = super.pollFirstEntry();
        inverse._remove(entry.getValue());
        return entry;
    }

    @Override
    public Map.Entry<K, V> pollLastEntry() {
        Map.Entry<K, V> entry = super.pollLastEntry();
        inverse._remove(entry.getValue());
        return entry;
    }
}
public类BiTreeMap扩展了TreeMap{
公共最终位图反转;
专用BiTreeMap(BiTreeMap反向){
这个。逆=逆;
}
公共比特映射(){
反向=新的位图(此);
}

公共位图(MapIt是一个问题?/practice?对于大学来说,我一直坚持先决条件,所以保留反向映射不是一个选项。元素只存在于一个地方。谢谢你的回答。在java中,元素总是只存在于一个地方,但是多个集合可以包含对同一对象的引用。通常,要做到这一点,我会ld实现我自己的集合,它封装了您所需的所有功能--这样,您可能有两个集合在其中执行工作,但您的集合是用户唯一会看到的集合。这也使得以后更改对您的要求时更容易进行更改。我不明白您的意思,我有compareTo(Comparable)和compare(Comparator)为元素实现的方法,但它们的实现方式与equals不兼容(这是一个先决条件),因此,在添加之前,我必须检查树集合中是否已经存在相等的元素。感谢您的回答。我只能使用标准Java集合,而保留反向映射不是一个选项。因此,我认为这是在具备这些先决条件的情况下实现这一点的唯一方法,因此我需要在另一部分进行优化。感谢您的回答。
public class BiTreeMap<K, V> extends TreeMap<K, V> {
    public final BiTreeMap<V, K> inverse;

    private BiTreeMap(BiTreeMap inverse) {
        this.inverse = inverse;
    }

    public BiTreeMap() {
        inverse = new BiTreeMap<V, K>(this);
    }

    public BiTreeMap(Map<? extends K, ? extends V> m) {
        inverse = new BiTreeMap<V, K>(this);
        putAll(m);
    }

    public BiTreeMap(Comparator<? super K> comparator) {
        super(comparator);
        inverse = new BiTreeMap<V, K>(this);
    }

    public BiTreeMap(Comparator<? super K> comparatorK, Comparator<? super V> comparatorV) {
        super(comparatorK);
        inverse = new BiTreeMap<V, K>(this, comparatorV);
    }

    private BiTreeMap(BiTreeMap<V, K> inverse, Comparator<? super K> comparatorK) {
        super(comparatorK);
        this.inverse = inverse;
    }

    @Override
    public V put(K key, V value) {
        if(key == null || value == null) {
            throw new NullPointerException();
        }
        V oldValue = super.put(key, value);
        if (oldValue != null && inverse._compareKeys(value, oldValue) != 0) {
            inverse._remove(oldValue);
        }
        K inverseOldKey = inverse._put(value, key);
        if (inverseOldKey != null && _compareKeys(key, inverseOldKey) != 0) {
            super.remove(inverseOldKey);
        }
        return oldValue;
    }

    private int _compareKeys(K k1, K k2) {
        Comparator<? super K> c = comparator();
        if (c == null) {
            Comparable<? super K> ck1 = (Comparable<? super K>) k1;
            return ck1.compareTo(k2);
        } else {
            return c.compare(k1, k2);
        }
    }

    private V _put(K key, V value) {
        return super.put(key, value);
    }

    @Override
    public V remove(Object key) {
        V value = super.remove(key);
        inverse._remove(value);
        return value;
    }

    private V _remove(Object key) {
        return super.remove(key);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        for (Map.Entry<? extends K, ? extends V> e : map.entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            put(key, value);
        }
    }

    @Override
    public void clear() {
        super.clear();
        inverse._clear();
    }

    private void _clear() {
        super.clear();
    }

    public boolean containsValue(Object value) {
        return inverse.containsKey(value);
    }

    @Override
    public Map.Entry<K, V> pollFirstEntry() {
        Map.Entry<K, V> entry = super.pollFirstEntry();
        inverse._remove(entry.getValue());
        return entry;
    }

    @Override
    public Map.Entry<K, V> pollLastEntry() {
        Map.Entry<K, V> entry = super.pollLastEntry();
        inverse._remove(entry.getValue());
        return entry;
    }
}