【问题标题】:In Java, what is the most memory efficient way to store large lists在 Java 中,存储大型列表的最节省内存的方法是什么
【发布时间】:2015-02-27 11:52:55
【问题描述】:

我必须比较两个大型整数数组(大约 150,000 个值),以查看哪些值是唯一的,哪些不是。我希望将输出存储在三个数据结构中,UniqueTo_A、UniqueTo_B 和 SharedElements。对于这种操作,我通常会使用 ArrayList 之类的东西,因为可以临时添加值,但是我知道 add() 和 remove() 的开销对于 ArrayLists 来说相当大。所以我的问题是:-在Java中,存储大型列表的最节省内存的方式是什么,可以动态添加项目,性能是关键。所有帮助或 cmets 将不胜感激。

编辑: 谢谢你是输入的人。 TheLostMind,我需要添加到数据集,但 Hashset 会促进这一点,所以我将继续使用 Hashset。 Nafas + NeplatnyUdaj 感谢您提供的示例。 Eckles,我应该掌握收藏品,我会研究这个以备下次使用。后续实施....

【问题讨论】:

  • 你会只在最后添加吗?..
  • 使用哈希集。当您使用Set.add 方法添加项目时,返回值会告诉您它是否已经存在。我不确定它是否最节省内存,但 150000 个数字不算什么,而且速度很快。 docs.oracle.com/javase/7/docs/api/java/util/Set.html#add%28E%29
  • 标准 Java HashSet 使用底层映射,因此如果您真的关心内存消耗,这不是最佳选择。我会寻找支持简单数据类型集合的附加库。如果您需要保护更多内存,您可能需要使用更多压缩方法。
  • 你更关心内存消耗还是运算速度?
  • @eckes 我同意你的看法。但是 Set 会消除很多复杂性,从而减少 Carbage Collection 和其他内部计算和内存使用。在实践中,使用类似 Set 的实现将使用更少的内存

标签: java performance list arraylist


【解决方案1】:

使用Set,因为,它adds在恒定时间内,它removes在恒定时间内有多个值。我每天使用 set 来存储超过数百万个对象。和removeAll 仍以毫秒为单位

Set<Integer> setA= new HashSet<Integer>();
Set<Integer> setB= new HashSet<Integer>();

//add stuff to setA and setB by add() method

Set<Integer> uniqueToA=new HashSet<Integer>(setA);
Set<Integer> uniqueToB=new HashSet<Integer>(setB);
Set<Integer> shared=new HashSet<Integer>();
shared.addAll(setA);
shared.addAll(setB);

uniqueToA.removeAll(setB);
uniqueToB.removeAll(setA);

shared.removeAll(uniqueToA);
shared.removeAll(uniqueToB);

System.out.println(uniqueToA);  //unique to A
System.out.println(uniqueToB); //unique To B
System.out.println(shared);  //shared

【讨论】:

    【解决方案2】:

    我认为列表不是一个很好的方法。你需要保持元素的顺序吗?单个列表可以包含重复条目吗?如果没有,那么我会像这样使用 HashSet:

        //initialization
        Random r = new Random();
        Set<Integer> aSet = new HashSet<Integer>();
        Set<Integer> bSet = new HashSet<Integer>();
        for (int i = 0; i< 150000; i++){
            aSet.add(r.nextInt());
            bSet.add(r.nextInt());
        }
    
        //Computation
        Set<Integer> aUnique = new HashSet<Integer>();
        Set<Integer> bUnique = new HashSet<Integer>(bSet); //we will remove duplicate entries later
        Set<Integer> shared = new HashSet<Integer>();
        for (Integer aval: aSet){
            if (bSet.contains(aval)){
                shared.add(aval);
            }else{
                aUnique.add(aval);
            }
        }
        bUnique.removeAll(shared);
    

    最后,你得到了三套要求的(aUniquebUniqueshared

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多