【问题标题】:Best approach to delete a set of entries in a Map删除地图中一组条目的最佳方法
【发布时间】:2017-09-06 12:17:35
【问题描述】:

是否有任何快速可靠的方法/方法可以根据条目值的属性删除一组条目。下面的方法循环每个不受欢迎的条目。 例如:ConcurrentHashMap - 条目将是数百万

    Iterator<Map.Entry<String, POJO>> iterator = map.entrySet().iterator();
    for (Iterator<Map.Entry<String, POJO>> it = iterator; it.hasNext(); ) {
        Map.Entry<String, POJO> entry = it.next();
        POJO value = entry.getValue();
        if (value != null && *attribute*.equalsIgnoreCase(value.getAttribute())) {
            it.remove();
        }
    }

【问题讨论】:

  • 数据库使用 indexes 来处理这些事情。因此,您可以使用另一个数据结构来跟踪具有特定属性的 POJO 标识符,或者使用不同的映射按属性对数据进行分区。但是这样做很容易使事情复杂化。您是否测量并确定这是您应用程序中的瓶颈?

标签: java


【解决方案1】:

没有更好的方法可以在不使用额外数据结构的情况下就地改变 map。您基本上要求的是二级索引,例如数据库中使用的二级索引,其中您有指向基于某些非主键属性的条目的指针。如果您不想存储额外的索引,没有比遍历所有条目更简单的方法了。

我建议您研究的是在原始地图上合成地图视图。例如(使用番石榴)

Map<String,POJO> smallerMap = Maps.filterValues(map, 
    v -> !attribute.equalsIgnoreCase(v.getAttribute())
);

您需要小心处理此类视图(例如,不要对其调用 size()),但对于访问等应该没问题(取决于您的确切需求、内存限制等)。

附注 - 请注意我已删除空值检查。您不能在 ConcurrentHashMap 中存储空值 - 在法线贴图中也不是什么好主意,最好删除整个键。

【讨论】:

  • 感谢您的建议!地图中维护的数据用作另一个流程的源数据。所以应该删除数据。地图上的数据将有多个添加、删除和更新请求。所以你建议的观点对这种情况没有帮助。
【解决方案2】:

我能想到两种解决方案

第一个解决方案:

创建另一个映射来存储对象哈希码作为键和对应的键作为值。结构可能如下所示

Map<Integer, String> map2 = new HashMap<>();

这是可行的解决方案。唯一的缺点是如果有大量对象,获取唯一的哈希码可能会很困难。

import java.util.HashMap;
import java.util.Map;

public class DualHashMap {

    public static void main(String a[]){

        Map<String, Pojo> map = new HashMap<>();
        Map<Integer, String> map2 = new HashMap<>();

        Pojo object1 = new Pojo();
        Pojo object2 = new Pojo();
        map.put( "key1", object1);
        map.put( "key2", object2);

        map2.put(object1.hashCode(), "key1");
        map2.put(object2.hashCode(), "key2");

        // Now let say you have to delete object1 you can do as follow
        map.remove(map2.get(object1.hashCode()));
    }
}


class Pojo{

    @Override
    public int hashCode(){
        return  super.hashCode(); //You must work on this yourself, and make sure hashcode is unique for each object
    }

}

第二个解决方案:-

使用 Guava 或 Apache 为双 hashmap 提供的解决方案

您需要的 Apache Commons 类是 BidiMap

这是Guava为你准备的另一个

【讨论】:

  • 1) 为什么在这里涉及哈希码? OP 希望对 getAttribute 进行索引,而不是哈希码。 2)你不能希望属性是唯一的——你需要使用 Multimap 之类的东西,而不是双向地图。 3) 不知道你想通过return this.hashCode() 显示什么,但它会进入无限循环。也许您的意思是 parent.hashCode()? (并不是说它很有意义)
  • 我说过 - hascode 可能是其中一种方式。我确信 OP 不会在其他任何地方使用哈希码。只需查看我在评论中明确写过的 hashcode 方法实现的 cmets。如果用户为POJO维护id,最好选择hashCode方法的返回。
猜你喜欢
  • 2010-09-21
  • 2011-05-23
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
相关资源
最近更新 更多