Java 成对的数据结构,其中每个值(成对)映射到另一个值?

Java 成对的数据结构,其中每个值(成对)映射到另一个值?,java,data-structures,map,Java,Data Structures,Map,我又带着一个类似的问题回来了。是否存在可以返回其特定伙伴的数据类型?例如: ExampleType<String,String> test = new ExampleType<String,String>(); test.put("hello","hi"); ExampleType测试=新的ExampleType(); 测试。输入(“你好”,“你好”); 如果我使用type test.get(“hi”),它将返回“hello”,如果我使用type test.get(“

我又带着一个类似的问题回来了。是否存在可以返回其特定伙伴的数据类型?例如:

ExampleType<String,String> test = new ExampleType<String,String>();
test.put("hello","hi");
ExampleType测试=新的ExampleType();
测试。输入(“你好”,“你好”);
如果我使用type test.get(“hi”),它将返回“hello”,如果我使用type test.get(“hello”),它将返回“hi”

我唯一的猜测可能是二维数组,但我不确定如何实现它。到目前为止,我能理解的唯一方法就是创建两个不同的hashmap并交换每个hashmap中的键。(显然这不是很有效)

谢谢你的帮助

您可以使用。它还支持反向查找:

bimap(或“双向映射”)是保留其值及其键唯一性的映射。此约束使bimap支持“反向视图”,这是另一个bimap,包含与此bimap相同的条目,但具有反向键和值


如果您已经依赖commons collections,那么您也可以使用内置的
BidiMap

,因此您可以使用第三方软件包,如Pangea提到的Guava's BiMap,或者,如果您想推出自己的产品,如果您需要两种不同的数据类型,那么2-maps的想法不错,如果键和值的类型相同,则可以使用具有两个条目的单个映射:

public class BiMap<T>{

    private Map<T,T> theMap = new HashMap<T,T>();

    public void put( T key, T value ){ put( key, value, false ); }
    public void forcePut( T key, T value ){ put( key, value, true ); }

    private void put( T key, T value, boolean force ){
        if( force || !theMap.containsKey(value) ){
            theMap.remove( theMap.remove( key ) );
            theMap.put( key, value );
            theMap.put( value, key );
        }else if( !theMap.get( value ).equals( key ) ){
            // If you allow null values&keys this will get more complicated.

            throw new IllegalArgumentException();
            // can make this more informative.
        }
        // else the pair is already in, there's nothing to do.
    }

    public T get( T key ){ return theMap.get( key ); }

    public T remove( T key ){
        T value = theMap.remove( key );
        if( value != null ) theMap.remove( value );
        return value;
    }
}
公共类BiMap{
私有映射theMap=newhashmap();
公共void put(T key,T value){put(key,value,false);}
public void forcePut(T key,T value){put(key,value,true);}
私有void put(T键、T值、布尔力){
if(强制| |!地图包含Y(值)){
映射移除(映射移除(键));
theMap.put(键、值);
theMap.put(值、键);
}如果(!theMap.get(value).equals(key))则为else{
//如果允许空值和键,这将变得更加复杂。
抛出新的IllegalArgumentException();
//可以使这更具信息性。
}
//否则这两个人已经进去了,没什么可做的。
}
public T get(T key){返回map.get(key);}
公共T删除(T键){
T值=贴图移除(键);
如果(值!=null),则删除映射(值);
返回值;
}
}
请注意,因为所有内容都是一个对象,所以就效率/空间而言,没有太多浪费:只存储了两次对象地址。这同样适用于你的两张地图的想法


此外,为了法规遵从性,添加必要的方法使其实现
Map
接口也不难。

两个ArrayList可能是最简单的。。只要确保将这些对存储在同一个索引中,它就会正常工作。代码看起来像:

ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
list1.add("hi");
list2.add("hello");
get("hi");

不知道这是否是最好的解决方案,但这是一个解决方案。

假设您不想区分您要查询的配对中的哪一部分(即,您想查看

test.get("hi") => "hello"
test.get("hello") => "hi"
为什么不将两个关键点插入同一个地图

test.put("hello","hi");
test.put("hi","hello");

有时“显而易见”的东西在旁观者的眼里。一对地图对我来说听起来很好。这是一个非常弱的解决方案。他已经在使用地图了,为什么要放弃继续使用地图?+1作为图书馆的建议。但是请注意,额外的限制可能使其不适用于所有类似的任务。(这是一个1-1映射,而不是带有反向查找映射的1-N映射。)我甚至可以扩展
HashMap
,如果你
put
重叠键,它会有“令人惊讶的”行为。
test.put(“a”,“b”);test.put(“a”,“c”);
test.get(test.get(“b”)
不返回
“b”
。很好。我会纠正它。我现在所拥有的
put
是一个肮脏的
forcePut
。我想它并不像我一开始在所有奇怪案例的测试中所想的那样优雅。
test.put("hello","hi");
test.put("hi","hello");