Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.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_Data Structures_Key Value - Fatal编程技术网

我应该使用Java中的哪种数据结构以有序的形式存储键值对?无多重记录

我应该使用Java中的哪种数据结构以有序的形式存储键值对?无多重记录,java,data-structures,key-value,Java,Data Structures,Key Value,我正在从事一个项目,我需要以有序的方式存储键值对(一对一映射)。然后我应该能够使用值检索键,使用键检索值。我看过地图、集合和哈希表,但它们不是有序的 另外,虽然很简单,但如果我们能够同时检索键和值,也就是说,接口支持这样的函数,那就太好了 编辑:键和值都是唯一的。维护插入的订单就足够了。应该适合您。通读链接应该适合您。通读链接您将需要两个LinkedHashMap。您可以创建内部使用两个LinkedHashMap的自定义类。一个用于将键映射到值,另一个用于将值映射到键。您将需要两个LinkedH

我正在从事一个项目,我需要以有序的方式存储键值对(一对一映射)。然后我应该能够使用值检索键,使用键检索值。我看过地图、集合和哈希表,但它们不是有序的

另外,虽然很简单,但如果我们能够同时检索键和值,也就是说,接口支持这样的函数,那就太好了


编辑:键和值都是唯一的。维护插入的订单就足够了。

应该适合您。通读链接应该适合您。通读链接

您将需要两个
LinkedHashMap
。您可以创建内部使用两个
LinkedHashMap
的自定义类。一个用于将键映射到值,另一个用于将值映射到键。

您将需要两个
LinkedHashMap
。您可以创建内部使用两个
LinkedHashMap
的自定义类。一个用于将键映射到值,另一个用于将值映射到键。

请注意,您没有定义什么是“有序的”。A允许按插入顺序对键(以及值)进行迭代。相反,a允许您使用比较器指定排序顺序,并确保添加到映射的所有项目都按排序顺序存储。100次中有99次,其中一个课程应该就是你所需要的。或者,谷歌的项目有几个非常好的实现,你可能会发现它们适合你的需要

我强烈警告您:如果您认为您需要的内容超出了这些课程所能提供的内容,那么您可能过度设计了您的问题。


出于无法完全证明的原因,我为您实现了一个合适的
UniqueOrderedBiMap
,它与Java集合框架兼容,并且所有实现的函数都能高效运行。您可以使用任何您认为合适的底层映射(如果您真的需要,包括一个未排序的映射),并且键和值总是唯一的。请注意,
LinkedHashMap
是一个非常薄的包装,因为这就是您所需要的,
LinkedHashMap
带有额外检查以确保值保持唯一性

出于好奇,请检查
UniqueOrderedMap
的此答案修订历史,该地图缺少
getKey()
removeKey()
方法,但更正确地实现了
Map
接口,只需要一个HashSet而不是HashMap来存储已知值

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class UniqueOrderedBiMap<K, V>implements Map<K, V> {
    private Map<K, V> orderedMap;
    private HashMap<V, K> valueMap;

    public UniqueOrderedBiMap() {
        this(new LinkedHashMap<K,V>());
    }

    public UniqueOrderedBiMap(Map<K, V> underlyingMap) {
        orderedMap = underlyingMap;
        valueMap = new HashMap<V, K>(orderedMap.size());

        for(Map.Entry<K, V> e : orderedMap.entrySet()) {
            if(!valueMap.containsKey(e.getValue())) { // Duplicate value
                // could instead fail softly by removing the associated item from the map, but this seems cleaner/clearer.
                // generally this constructor should be passed an empty map anyways
                throw new IllegalArgumentException("Duplicate value "+e.getValue()+" found in underlying map.");
            }
            valueMap.put(e.getValue(), e.getKey());
        }
    }

    @Override
    public int size() {
        return orderedMap.size();
    }

    @Override
    public boolean isEmpty() {
        return orderedMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return orderedMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        // more efficient than iterating over the map
        return valueMap.containsKey(value);
    }

    @Override
    public V get(Object key) {
        return orderedMap.get(key);
    }

    public K getKey(V value) {
        return valueMap.get(value);
    }

    // Likely want to implement a forcePut(K, V) method like Guava's BiMaps do
    @Override
    public V put(K key, V value) {
        if(valueMap.containsKey(value)) {
            throw new IllegalArgumentException("Cannot insert non-unique value "+value);
        }
        V ret = orderedMap.put(key, value);
        valueMap.remove(ret);
        valueMap.put(value, key);
        return ret;
    }

    @Override
    public V remove(Object key) {
        V ret = orderedMap.remove(key);
        valueMap.remove(ret);
        return ret;
    }

    public K removeKey(V value) {
        K ret = valueMap.remove(value);
        orderedMap.remove(ret);
        return ret;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        // Existing Map implementation's putAll have some optimizations we
        // could take advantage of, but this isn't unreasonable for a first pass
        for(Entry<? extends K, ? extends V> e : m.entrySet()) {
            put(e.getKey(), e.getValue());
        }
    }

    @Override
    public void clear() {
        orderedMap.clear();
        valueMap.clear();
    }

    @Override
    public Set<K> keySet() {
        return orderedMap.keySet();
    }

    @Override
    public Collection<V> values() {
        return orderedMap.values();
    }

    @Override
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        return orderedMap.entrySet();
    }

    @Override
    public boolean equals(Object o) {
        if(o instanceof UniqueOrderedBiMap) {
            UniqueOrderedBiMap<?,?> map = (UniqueOrderedBiMap<?,?>)o;
            return orderedMap.equals(map.orderedMap); 
        }
        return false;
    }

    @Override
    public int hashCode() {
        return orderedMap.hashCode();
    }

    @Override public String toString() {
        return orderedMap.toString();
    }

    public static void main(String[] args) {
        String[] names = { "Marcus", "Jim", "Tom", "Sam" };
        String[] grades = { "A", "B", "D", "F" };

        UniqueOrderedBiMap<String,String> insertionMap = new UniqueOrderedBiMap<>();
        UniqueOrderedBiMap<String,String> sortedMap = new UniqueOrderedBiMap<>(new TreeMap<String,String>());

        for(int i = 0; i < names.length; i++) {
            insertionMap.put(names[i], grades[i]);
            sortedMap.put(names[i], grades[i]);
        }

        // Poor man's assert
        System.out.println(insertionMap.toString().equals("{Marcus=A, Jim=B, Tom=D, Sam=F}"));
        System.out.println(sortedMap.toString().equals("{Jim=B, Marcus=A, Sam=F, Tom=D}"));

        insertionMap.put("Tom", "C");
        sortedMap.put("Tom", "C");
        System.out.println(insertionMap.toString().equals("{Marcus=A, Jim=B, Tom=C, Sam=F}"));
        System.out.println(sortedMap.toString().equals("{Jim=B, Marcus=A, Sam=F, Tom=C}"));

        try {
            insertionMap.put("Sam", "C");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
        try {
            sortedMap.put("Sam", "C");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }

        insertionMap.remove("Tom");
        sortedMap.remove("Tom");
        insertionMap.put("Sam", "C");
        sortedMap.put("Sam", "C");
        System.out.println(insertionMap.toString().equals("{Marcus=A, Jim=B, Sam=C}"));
        System.out.println(sortedMap.toString().equals("{Jim=B, Marcus=A, Sam=C}"));

        insertionMap.removeKey("A");
        sortedMap.removeKey("A");
        System.out.println(insertionMap.toString().equals("{Jim=B, Sam=C}"));
        System.out.println(sortedMap.toString().equals("{Jim=B, Sam=C}"));
    }
}
import java.util.Collection;
导入java.util.HashMap;
导入java.util.LinkedHashMap;
导入java.util.Map;
导入java.util.Set;
导入java.util.TreeMap;
公共类UniqueOrderedBiMapiImplements映射{
私有地图有序地图;
私有HashMap-valueMap;
公共UniqueOrderedBiMap(){
此(新LinkedHashMap());
}
公共UniqueOrderedBiMap(地图下的地图){
orderedMap=参考地图;
valueMap=newhashmap(orderedMap.size());
对于(Map.Entry e:orderedMap.entrySet()){
如果(!valueMap.containsKey(e.getValue()){//重复值
//相反,可以通过从映射中删除相关项来柔和地失败,但这看起来更清晰。
//通常,无论如何都应该向该构造函数传递一个空映射
抛出新的IllegalArgumentException(“在基础映射中找到重复值”+e.getValue()+);
}
put(e.getValue(),e.getKey());
}
}
@凌驾
公共整数大小(){
return orderedMap.size();
}
@凌驾
公共布尔值为空(){
return orderedMap.isEmpty();
}
@凌驾
公共布尔containsKey(对象键){
返回orderedMap.containsKey(键);
}
@凌驾
公共布尔包含值(对象值){
//比在地图上迭代更有效
返回valueMap.containsKey(值);
}
@凌驾
public V get(对象键){
returnorderedmap.get(键);
}
公共K getKey(V值){
返回valueMap.get(值);
}
//可能想要实现一个forcePut(K,V)方法,就像Guava的BiMaps一样
@凌驾
公共V输入(K键,V值){
if(valueMap.containsKey(值)){
抛出新的IllegalArgumentException(“无法插入非唯一值”+值);
}
V ret=orderedMap.put(键,值);
valueMap.remove(ret);
valueMap.put(值、键);
返回ret;
}
@凌驾
公共V删除(对象密钥){
V ret=orderedMap.remove(键);
valueMap.remove(ret);
返回ret;
}
公共K removeKey(V值){
K ret=valueMap.remove(值);
orderedMap.remove(ret);
返回ret;
}
@凌驾
公共空间(地图)o;
返回orderedMap.equals(map.orderedMap);
}
返回false;
}
@凌驾
公共int hashCode(){
return orderedMap.hashCode();
}
@重写公共字符串toString(){
return orderedMap.toString();
}
公共静态void main(字符串[]args){
String[]name={“Marcus”、“Jim”、“Tom”、“Sam”};
字符串[]等级={“A”、“B”、“D”、“F”};
UniqueOrderedBiMap insertionMap=新的UniqueOrderedBiMap();
UniqueOrderedBiMap sortedMap=新的UniqueOrderedBiMap(新树映射());
for(int i=0;i