【问题标题】:Get a HashSet out of the keys of a HashMap?从 HashMap 的键中获取 HashSet?
【发布时间】:2010-12-10 04:40:59
【问题描述】:

我有一个相当大的(100'000 个条目)HashMap。现在,我需要一个HashSet,其中包含来自此HashMap 的所有键。不幸的是,HashMap 只有一个 keySet() 方法,它返回一个 Set 而不是一个 HashSet

使用 Java 生成这样的HashSet 的有效方法是什么?

【问题讨论】:

  • 为什么需要一个 HashSet 而不仅仅是一个 Set?
  • 我必须调用的方法需要一个HashSet,而相应的代码不是我写的。
  • 哇。编写该方法的人需要很好的交谈。 :)
  • +1 您的评论说明了一切。很高兴您找到了解决方案。 :-)
  • @Haes:您应该知道性能受到影响。当您从 keySet() 构造 HashSet 时,它基本上必须复制整个集合。我不确定在 100,000 个元素上执行此操作需要多长时间,但它肯定会占用大量内存。我知道你没有其他选择,但这可能会给你更多的弹药来请求编写方法的人来更改它,因此它需要一个 Set 而不是 HashSet。 (除非他们在做一些非常奇怪的事情,否则他们应该能够只更改参数,其余部分无需修改即可工作)。

标签: java hashmap hashset


【解决方案1】:
HashSet myHashSet = new HashSet(myHashMap.keySet());

没试过。

【讨论】:

    【解决方案2】:

    您不能从现有的Set 创建HashSet 吗?但是(更重要的是)您为什么担心 keySet() 方法返回给您的实现?

    【讨论】:

      【解决方案3】:

      设置 set=new HashSet(map.keySet());

      【讨论】:

        【解决方案4】:

        为什么你特别需要一个 HashSet?

        任何 Set 都具有相同的接口,因此通常可以互换使用,因为良好的做法要求您对所有 Set 都使用 Set 接口。


        如果你真的需要,你可以从另一个创建一个。对于通用代码,它可能是:

            Map<B, V> map = ...;
            HashSet<B> set = new HashSet<B>(map.keySet());
        

        【讨论】:

        • 如果你打算这样做,为什么不直接使用 Set&lt;B&gt; set = map.keySet(); 呢?如果需要实际的 HashSet,set 应该是 HashSet,而不是 Set。如果set可以是Set,则不需要调用HashSet构造函数
        • 谢谢,下次我更好的 RTFM ;)
        • @Kip 感谢您的有用评论。我稍微澄清了我的代码示例以将其考虑在内。
        • 基普:你是对的。实际上,我使用了以下代码: HashSet set = new HashSet(map.keySet());
        • 为什么你特别需要一个 HashSet? 因为 HashSet 是可序列化的,而 LinkedKeySet 不是:)
        【解决方案5】:

        假设“高效”这个词是您问题的关键部分,并且取决于您想对集合做什么,创建您自己的 HashSet 子类可能是一个想法,该子类忽略 HashSet 实现并呈现一个视图而是放到现有的地图上。

        作为一个部分实现的示例,它可能看起来像:

        public class MapBackedHashSet extends HashSet
        {
            private HashMap theMap;
        
            public MapBackedHashSet(HashMap theMap)
            {
                this.theMap = theMap;
            }
        
            @Override
            public boolean contains(Object o) 
            {
                return theMap.containsKey(o);
            }
        
            /* etc... */
        }
        

        如果您不知道如何使用该类,则需要注意覆盖所有相关方法。

        【讨论】:

        • 它应该是一个 SetBackedHashSet 为他工作,使用一个 Set 作为后备数据。他从keySet() 得到的原始对象是 Set,而不是 HashMap。
        • 重点是不需要用这种方式提取集合。这是为了避免从可能大量的对象中创建新的哈希。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        • 2010-11-25
        • 2016-03-08
        • 2013-04-21
        相关资源
        最近更新 更多