`
lenozhi
  • 浏览: 52298 次
社区版块
存档分类
最新评论

将HashMap文件化

阅读更多

   ( 只是个想法加雏形,实现的很丑陋且效率很低下)

    有这样一种场景,校验千万行文本中某一列键值(长度30以上)的唯一性(要求100%准确)。按我的水平,自然就想到用HashMap,可这样就会将所有的键值都放入内存,对内存资源需求较大。然后我就想,数据库也有一样的需求呀,人家怎么搞的呢?思前想后,能力太有限,没思路。最后只能想到,如果把HashMap的存储介质由内存转移到外存(文件中),貌似会节省相当部分的内存(此假设未经证实)。于是着手改造,HashMap实现的主要算法基本了解只是对于寻址那块要从内存转入文件,这是关键。由此做了如下设计:

 

HashMap的put方法中:

由hashcode算出在table中的位置i,然后以table[i]为链首存储元素。

 

我的思路:

建一个索引文件,每个索引的结构:数据项+后继索引位置。索引长度:数据项长度+long型的长度(8字节)

table[i]即链首的位置 = i * 数据项长度+8

当首次写入链首时,索引位置埴0,因为下一个元素未知嘛。

当table[i]第n个元素写入时,从链首开始遍历(取后继索引位置,跳转至该位置),直到遍历索引位置为0的链表元素,将要写入第n个元素的文件位置记到此后继索引位置,并将第n个元素写入文件。如果遍历时发现,当前元素数据项与要写入元素的数据项值相同,则发现重复元素。

 

 

 

目前的问题:

1. io操作过多,考虑是不是可以通过内存映像文件来提高提高效率。当然加加cache也行,就是没考虑好怎么加。

2. 还木有想到。。。

 

 

上传了我丑陋的代码,运行FileMap就好。 

 

试用了一下jdbm-2.0.jar这个包,100万行数据插入,就是从1到100万,10行一提交。共用了38秒。使用内存14M左右,太NB。严重鄙视我提交的烂代码。

分享到:
评论
12 楼 mtnt2008 2011-04-20  
lenozhi 写道
kimmking 写道
直接用hashcode呗。

咋叫直接用hashcode,两个键值的hashcode相同咋办


hash冲突的处理方法:1.开放地址法 2.地址链法 3.再hash发

以前的一个思路:

1.把value通过MappedByteBuffer(java的内存文件映射)存入硬盘得到文件偏移量d;

2.对key做hash,以这个值为index,进行操作:桶数组[index] = d

3.如果发生hash冲突,选用一个处理hash冲突的方法
11 楼 JE帐号 2011-04-20  
我的印象里java的io操作是比较弱的,文件操作性能很差.
所以说,新拿到一个值,虽然你可以算出来应该在什么位置,并用skip直接定位过去,可是在io内部还是给read中间哪些值. 再说,你向文件里插入一个值,我印象是不可能向链表似的前后改下索引就行了,好像给整个复制....

所以,我觉得这个事情,最后的比对最好还是放在内存里,第一步就是把大文件分割为很多分范围的小文件(可以理解为一个大粒度的排序),然后具体查找重复项时还是把文件读入内存即可.

毕竟千万个数据虽多,但是使劲的分一分,一个小文件也占不了多少内存..


反正,我以前用io的时候就是这个印象.
所以我一直觉得数据库应该对于文件系统的操作进行了底层的控制,比如从10000跳到20000,他是直接跳过去找到,而不是顺序读过去的.
10 楼 lenozhi 2011-04-20  
JE帐号 写道
lenozhi 写道
JE帐号 写道
千万行文本? 大概多大?
可以先考虑遍历一遍,然后把键值按范围先分割到几百个小文件中.然后再查找重复的.
虽然多读取一遍,但循环规模可以大大减小.


范围以什么划分?感觉基本上hashcode是我能想到且用到的最好的手段了。这个思路感觉上跟我上面写的类似,只不过我放到一个文件里了。划分到几百文件,其实就是hashmap内部实现的table


我觉得,其实怎么划分还是要看你那个30位的数字串的特点.尽量让结果平均点.

重点在于分割,这样你的比较规模能小很多.

这话对,有几组可以从业务角度分割。
9 楼 JE帐号 2011-04-20  
lenozhi 写道
JE帐号 写道
千万行文本? 大概多大?
可以先考虑遍历一遍,然后把键值按范围先分割到几百个小文件中.然后再查找重复的.
虽然多读取一遍,但循环规模可以大大减小.


范围以什么划分?感觉基本上hashcode是我能想到且用到的最好的手段了。这个思路感觉上跟我上面写的类似,只不过我放到一个文件里了。划分到几百文件,其实就是hashmap内部实现的table


我觉得,其实怎么划分还是要看你那个30位的数字串的特点.尽量让结果平均点.

重点在于分割,这样你的比较规模能小很多.
8 楼 lenozhi 2011-04-20  
JE帐号 写道
千万行文本? 大概多大?
可以先考虑遍历一遍,然后把键值按范围先分割到几百个小文件中.然后再查找重复的.
虽然多读取一遍,但循环规模可以大大减小.


范围以什么划分?感觉基本上hashcode是我能想到且用到的最好的手段了。这个思路感觉上跟我上面写的类似,只不过我放到一个文件里了。划分到几百文件,其实就是hashmap内部实现的table
7 楼 JE帐号 2011-04-20  
千万行文本? 大概多大?
可以先考虑遍历一遍,然后把键值按范围先分割到几百个小文件中.然后再查找重复的.
虽然多读取一遍,但循环规模可以大大减小.

或者直接利用数据来找,遍历一遍存到数据库中,然后一条sql...
6 楼 lenozhi 2011-04-20  
dennis_zane 写道
lenozhi 写道
dennis_zane 写道
感觉你需要的是布隆过滤器。


非100%准确排重


那么再加个md5计算比较,基本上可以达到接近100%的正确率,当然还是要看你项目要求了。


资金账号比较,还是不能用接近,呵呵。还有什么高见。我就是觉得数据库的唯一索引很行,不明白其实现原理,给讲讲不?
5 楼 dennis_zane 2011-04-20  
lenozhi 写道
dennis_zane 写道
感觉你需要的是布隆过滤器。


非100%准确排重


那么再加个md5计算比较,基本上可以达到接近100%的正确率,当然还是要看你项目要求了。
4 楼 lenozhi 2011-04-20  
dennis_zane 写道
感觉你需要的是布隆过滤器。


非100%准确排重
3 楼 dennis_zane 2011-04-20  
感觉你需要的是布隆过滤器。
2 楼 lenozhi 2011-04-20  
kimmking 写道
直接用hashcode呗。

咋叫直接用hashcode,两个键值的hashcode相同咋办
1 楼 kimmking 2011-04-20  
直接用hashcode呗。

相关推荐

    基于JavaScript的HashMap实现

    1. **初始化**:构造函数可以接收初始容量和负载因子作为参数,用于设置HashMap的初始大小和何时进行扩容。 2. **插入**:`put(key, value)`方法允许我们将键值对插入HashMap中。如果键已经存在,则更新对应的值。 ...

    java中HashMap详解.pdf

    在给定的文件中,我们看到了HashMap的初始化和添加元素的操作。例如,通过以下代码创建了一个HashMap实例,并向其中添加了三个元素: ```java HashMap, Double> map = new HashMap, Double>(); map.put("key1", ...

    hashmap 集合

    1. 初始化容量:避免HashMap自动扩容,可以预估数据量并设定合适的初始容量,如`new HashMap(预计数量 * 2)`,这样可以减少扩容带来的额外开销。 2. 键值对的哈希函数:确保键对象的hashCode()和equals()方法正确...

    jdom 解析xml存入hashmap的例子

    本篇将详细介绍如何使用JDOM解析XML文件,并将其内容存入HashMap中。 首先,我们需要了解JDOM的基本使用。JDOM的核心类包括`SAXBuilder`用于解析XML文档,`Document`表示整个XML文档,`Element`代表XML的元素节点,...

    基于共享内存的hashmap

    2. HashMap:HashMap是一种动态数组和链表相结合的数据结构,它使用哈希函数将键映射到数组的特定位置,以便快速查找、添加和删除元素。在Java中,HashMap是内置的集合类,而在C++中,可以使用STL中的`std::...

    C++hashmap的使用实例

    在C++编程中,`hashmap`通常指的是`std::unordered_map`,它是一个关联容器,提供了基于哈希表的键值对存储。这个数据结构允许我们以接近常数时间的复杂度进行插入、查找和删除操作,极大地提高了程序的执行效率。...

    hashmap学员简单增删改查 序列化

    - **添加学生**:调用`ddd`方法,提示用户输入学号、姓名和身高,然后创建`Student`对象并将其存入`HashMap`。 - **查询学生**:调用`fff`方法,提示用户输入学号,检查该学号是否存在于`HashMap`中,如果存在,则...

    c语言 hashmap

    哈希表(Hashmap)是一种常见的数据结构,它在计算机科学和编程中扮演着重要的角色。在C语言中实现哈希表,可以帮助我们快速地存储和查找数据,尤其是在需要高效查找性能的应用场景下。本节将详细介绍如何用C语言...

    深入理解Java之HashMap —— 03

    现在,我们来详细分析给定的文件中提到的HashMap的构造函数和操作流程: 1. **HashMap的构造函数**: HashMap的构造函数允许用户指定初始容量(initialCapacity)和负载因子(loadFactor)。如果初始容量小于0或...

    源码解析jdk8.0集合:HashMap的底层实现原理.pdf

    根据提供的文件信息,以下是对JDK 8.0中HashMap实现原理的详细知识点介绍: 1. HashMap概述 HashMap是Java集合框架的一部分,它实现了Map接口,用于存储键值对。其核心特点在于基于哈希表的映射机制,能够通过键...

    JSON入门Java篇-4-用HashMap来构建JSON.rar

    除了将HashMap转换为JSON,Gson还提供了反序列化的功能,即将JSON字符串转换回HashMap。例如: ```java Type type = new TypeToken<HashMap, Object>>(){}.getType(); HashMap, Object> deserializedMap = gson.from...

    test-hashmap.rar_Fun_ Fun_ Fun_linux hashmap

    在"test-hashmap.c"文件中,我们可以期待找到以下内容: 1. **哈希函数**:这是将键转化为数组索引的算法。一个好的哈希函数应尽可能均匀地分布键,以减少冲突并最大化效率。可能包含了一些数学运算,如取模、异或...

    基于HashMap的学生管理系统

    本篇将深入探讨如何利用Java中的HashMap类来构建一个高效的学生管理系统。 HashMap是Java集合框架中的一员,它是一个散列映射数据结构,提供了键值对的存储方式。HashMap的特点在于其查找和插入操作的时间复杂度...

    HashMap-master.zip_hash

    可以期待在这里找到Java或其他编程语言的源文件,这些文件可能包含了HashMap类以及相关的哈希函数实现。 在深入学习HashMap时,了解其内部机制如链地址法、开放寻址法处理冲突,以及负载因子(Load Factor)对性能...

    逆向-音乐学家方大刚-快速定位hashMap

    3. **数据流分析**:通过跟踪函数间的调用关系和数据流动,理解HashMap的结构是如何被初始化、更新和查询的。这可能涉及到对指针解引用、内存布局的理解以及动态分析。 4. **哈希函数分析**:HashMap的关键在于它的...

    HashMap.pdf

    根据提供的文件信息,以下是详细的IT知识点: 1. JDK版本对HashMap实现的改变: - JDK1.7中的HashMap基于数组+链表实现,插入元素时使用的是链表尾部插入。 - JDK1.8中,当链表长度达到8并且容量达到64时,链表会...

    java7hashmap源码-java:Java

    hashmap源码 Table Of Contents day01_JAVA语言概述与基本语法:标识符、变量也变量分类、源码_反码_补码、进制转换、编码与字符集 day02_基本语法.运算符:算术运算符、赋值运算符、比较运算符、逻辑运算符、位...

    Practice-HashMap:我的java.util.HashMap实现

    在这个实践中,你可能需要关注的文件包括源代码文件(如`.java`文件),其中包含了`HashMap`类的实现,可能包括内部的`Entry`类用于表示键值对,以及各种方法的实现。此外,测试文件(如`.test`或`.java`测试类)...

    React_HashMap_Visualizer

    在这个项目中,`React_HashMap_Visualizer-master`很可能是项目的源代码仓库,包含了项目的所有文件和目录。通常,一个React项目会包含以下关键部分: 1. `public` 文件夹:存放静态资源,如HTML入口文件(index....

    HashMap关系数据映射技术软件jadepool-community-3.0

    JadePool3.0的主要变化是: 1、支持JTA分布式事务; 2、调整了DbCenter实例; 3、优化了键值生成器方法,并做了高并发性能测试;...JadePool3.0除了具备了简洁、高效、智能化的特性之外,还具备高并发性、高稳定性。

Global site tag (gtag.js) - Google Analytics