Java HashMap/List替代方案,用于海量数据

Java HashMap/List替代方案,用于海量数据,java,memory,hashmap,Java,Memory,Hashmap,在我的Java应用程序中,我必须扫描一个文件系统并递归地存储已创建文件的路径,以便进行早期搜索 我尝试将List/ArrayList和HashMap作为存储结构,但当文件系统包含1.000.000+个文件时,内存使用量太大 如何在不使用一半RAM(8GB)的情况下存储和快速检索这些“字符串” 在全局hashmap中,您可以存储指向Dir对象的指针,而不是将完整路径存储为字符串 为找到的每个目录创建一个Dir对象。每个Dir对象都有一个指向其父Dir对象及其本地名称的指针 例如: /a/long.

在我的Java应用程序中,我必须扫描一个文件系统并递归地存储已创建文件的路径,以便进行早期搜索

我尝试将List/ArrayList和HashMap作为存储结构,但当文件系统包含1.000.000+个文件时,内存使用量太大


如何在不使用一半RAM(8GB)的情况下存储和快速检索这些“字符串”

在全局hashmap中,您可以存储指向Dir对象的指针,而不是将完整路径存储为字符串

为找到的每个目录创建一个Dir对象。每个Dir对象都有一个指向其父Dir对象及其本地名称的指针

例如:

/a/long...path/p/   is a Dir you already found.
/a/long...path/p/a
/a/long...path/p/b  are two new Dirs
这两个子目录只需存储对父目录的引用以及它们的本地名称“a”或“b”


注意,您不必首先找到父对象:当扫描文件系统时,您应该递归地或显式地使用堆栈来执行此操作。当您创建一个Dir对象(例如这里的/p)时,您可以将该对象推到堆栈上,然后访问(进入)该目录。创建/a和/b子目录时,只需查看堆栈顶部即可找到它们的父目录。当您处理完
/a/long…path/p/
的全部内容后,您将从堆栈中弹出表示它的Dir对象。

您将在主内存中存储大量字符串。无论您使用的数据结构如何,这都需要内存。一种方法可能不是一直存储整个路径,而是将它们存储在层次结构中结构例如,将目录名作为键存储在映射中,并将该目录的所有值作为值递归存储在列表中。

这个问题可以有很多答案。人们可以提供多种数据结构供您使用,也可以要求您增加硬件内存或JVM的堆大小。但我认为问题出在别的地方

仅使用基本数据结构无法解决此问题。这也可能需要在设计级别进行更改。想想你的需要。您要求的是如此巨大的空间,而今天的操作系统甚至是存储着非常大数据的RDBMS都不需要这样的空间

数据结构即服务(DSAS-它已经存在,例如redis,但嘿,我可能创造了这个术语!)

在应用程序设计中,尝试引入redis、memcached或couchdb等组件或服务,这些组件或服务专门用于“存储大量数据”、“通过标准套接字或其他高速通信协议(如DBUS)进行快速搜索”


不要担心这些协议的内部工作。有足够的库/API为您完成这项工作

我建议您使用HashSet并存储路径的md5 sum:

Set<Md5Sum> paths = new HashSet<>();
//for each path
String path = ...
byte[] md5 = messageDigestObject.update(path.getBytes());
path.add(new Md5Sum(md5));
关于更新


您需要重新扫描文件系统并重新创建此哈希集对象,或者您可以订阅文件系统事件(请参阅)。

我建议将该数据转储到文件或数据库中。一个纯文本文件就可以了。你们多久扫描一次文件系统?我们可以说它是常数吗?是的,我已经尝试了DB,但我失去了“速度”,因为我需要在执行过程中多次搜索单个条目。HashMap和ContainesKey在O(1)时间内给我一个结果,但DB没有。不,sibnick,这个文件系统可以更改…每次扫描都可以更改different@user3357127-具有1.000.000+条记录的hashmap几乎总是会发生冲突,因此效率不会降低
O(1)
如果我存储对象,我如何快速搜索hashmap中的路径?循环将非常耗时..我想我必须更好地解释我的情况:我有一个存储了路径的SQL DB,然后我扫描文件系统,我必须检查我找到的每个文件,如果这个文件(确切路径)已经在我的DB中。我正在寻找一种快速且低内存使用率的方法…@user3357127您可以将hashmap中的多个引用存储到Dir对象。示例:如果访问
/a/long…path/p/b/x.txt
,则可以在hashmap键
x.txt
b
下存储对它的引用。然后,您需要一个multihashmap或在每个hashmap条目中存储一个向量。是的,但问题是a可能会找到许多x.txt文件…密钥将是overriden@user3357127对于这个场景,您需要一个multihashmap或在每个hashmap条目中存储一个向量。向量条目引用Dir-objs.Redis,我认为这是一个很好的方法!我看到它也有java api(jedis),但我不明白它是创建一个永久的“db”,还是只是在运行时运行每个程序……redis也有创建永久db的配置。请查看更多信息。
class Md5Sum{
    //it is more memory effiecient than byte[]
    long part1, part2;
    //override equals and hashCode methods
    //..........
}