从HashMap获取匹配的对象类型

时间:2017-02-05 21:01:27

标签: java loops hashmap

首先,我想说我对编程很新。 我存储了一些"扩展"在同一个HashMap中的超类。 (例如XY和XZ扩展X - 我在同一个HashMap中存储X&#,s&x;和XZ' s)。 我决定这样做是为了方便 - 通常每次我做某事时,我都需要扩展的所有课程" X" - 在这个例子中" XY"和" XZ"。当我想检查单个值是否是指定类型对象的实例时也没有问题 - 我只是使用" instanceof"式。让我们说我想检查一下密钥的对象" key"是" XY"的实例:

X objectoftypeX = hashmap.get(key)
if(objectoftypeX instanceof XY){
    //do stuff
}

但是我的问题来了:如何只在这个HashMap中迭代,例如,XY? 这可能不单独检查每个对象吗? 这样做有意义吗? 希望你能理解我的问题。

4 个答案:

答案 0 :(得分:5)

地图是相当简单的结构,可以优化一种访问形式(按键查找)。如果您希望能够快速查找特定类型的项目,则需要使用不同的结构。

例如,您可以选择制作多个地图,或制作嵌套地图:

// Nested map, with the top level map indexing by Type (can be a String)
// and the maps inside it indexing by a String key.
Map<Type, Map<String, Object>> map = ...;

如果您不介意单独检查每个条目的开销,您可以通过流轻松获得所需的所有元素:

List<XY> list = hashmap.values().stream()
    .filter(v -> v instanceof XY)  // check type
    .map(v -> (XY) v)   // do cast
    .collect(Collectors.toList());  // collect to list

答案 1 :(得分:2)

hashmap.entrySet().filter(item -> item.value() instanceOf X).forEach(item -> ...);

它是相同的,但射手

答案 2 :(得分:0)

    final Object[] keySetArray = mMap.keySet().toArray();
for( int x = 0; x < keySetArray.length; x++ )
{
        final Object whatStored = mMap.get( keySetArray[x] );
        System.out.println("key[" + keySetArray[x] + "]: "+ whatStored );
    // Make sure this check happens as it is, if you stored XY and XZ that extended X  
         if( whatStored instanceof of XY || whatStored instanceof XZ )
         {
             if( whatStored instanceof XY )
             {
                  // Go here for instance X and XY
             }
             else if( whatStored instanceof XZ )
             {
                 // Go here for instance X and XZ
             }
         }
}

希望这是关闭??

答案 3 :(得分:0)

使用标准的hashmap,不可能有效地完成这项工作(无需经历所有事情)。 hashmap的目的是提供对元素的快速访问,只需很小的内存开销。考虑你有一个整数大小的数组和一个hashcode函数,它为每个存储的对象返回整数。然后,您将能够通过应用index = hashcode(key)找到该元素,这基本上是1个操作来查找任何内容。但是你有一个可怕的内存开销(数组大小等于所有整数)。

其他选项包括列表并浏览所有元素。在这里你没有内存开销,但搜索复杂性将是O(n) - 你需要经历所有事情以确保元素不在数组中(或者更快地找到它)。

Hashmap位于中间位置。你分配大小的数组让我们说100.然后你计算密钥的哈希码函数,结果是105.所以你把对象放在索引{hashcode_result} modulo array_size上。在我们的例子中,105%100 == 5。

有趣的东西取决于实现,你会做什么,如果你有碰撞,它作为一个具有相同位置的key2。例如,如果哈希码值为205,305 ...(对于所有这些哈希码,模数将为5)。 一种可能性是将这些额外的元素添加到下一个可用的索引6,7 ... 在java中(或者至少据我记得),存储桶是作为链表实现的,所以你将拥有

0 => []
1 => []
2 => []
3 => []
4 => []
5 => [k=105, k=205, k=305...]  

如何在您的用例中使用hashmap的唯一方法是实现一个hashcode函数,该函数总是为同一个类生成相同的哈希值。但这会将散列映射简化为n个列表,其中n是子类的数量。并且查找将非常糟糕(您将不得不进行M / n操作来查找值,其中M是元素的数量,n是不同类的数量),而正确实现的hashmap(哈希码值的均匀分布)保证了查找次数实际上等于1。

长话短说 - 由于hashmap的结构,你不能有效地做任何类型的数据相关的loopkup(你将杀死搜索列表的性能)。 如果你想进行这种类型的查询, john16384 的答案是非常好的。