Java开发中各种集合框架简介
在大数据MapReduce作业开发中,我们经常会遇到一些大小表的join,这是如果这个小表足够“小”的话,我们可以使用进行“map-join-side”,这要就可以有效的降低reduce端的压力,但是在常用的JDK的集合中的Map有些许鸡肋,因此,各路大神们针对这个问题开发出了不同的集合框架,用以替换原始集合,下面我们具体介绍几种常用的集合框架:
首先,我们设想了一个场景——计算不同事业部015、2016年老客,新客-转化,新客-新增的用户数量,这三种类型的用户的定义如下:
老客:前一年和当前年均购买过服百事业部商品
新客-转化:前一年购买过图书,当前年购买了服百事业部商品
新客-新增:前一年什么也没买,当前年购买了服百事业部商品
因此,根据上述定义,举例:2016年老客就是根据cust_id(用户ID)在服百分类(fubaiArrayList )和服百总和(fubaiAllArrayList )两个集合查看2016年和2015年均存在的用户。2016年新客-转化就是根据cust_id(用户ID)在图书(bookArrayList )存在2015年购买记录,在服百分类(fubaiArrayList )和服百总和(fubaiAllArrayList )两个集合查看2016年存在的用户。2016年新客-新增就是根据cust_id(用户ID)在所有用户(allArrayList )不存在2015年购买记录,但在服百分类(fubaiArrayList )和服百总和(fubaiAllArrayList )两个集合查看2016年存在的用户。
因此,根据上述解释,我们构造了原始实现代码为:
public static class Map extends Mapper<LongWritable, Text, Text, Text> {
public static ArrayList<String> bookArrayList = null;
public static ArrayList<String> fubaiAllArrayList = null;
public static ArrayList<String> fubaiArrayList = null;
public static ArrayList<String> allArrayList = null;
@Override
protected void setup(Mapper<LongWritable, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
bookArrayList = new ArrayList<String>();
Configuration configuration = context.getConfiguration();
FileSystem fs = FileSystem.get(configuration);
InputStream in = null;
BufferedReader reader = null;
String tempString = null;
Path book_path = new Path("/personal/zhoujie/recommend/book.csv");//14 15年全年购买过书的用户名单
if (fs.exists(book_path)) {
in = fs.open(book_path);
reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
while ((tempString = reader.readLine()) != null) {
//年份 cust_id 图书事业部
String parts[] = tempString.split(TAB, -1);
if(parts.length!=3)continue;
bookArrayList.add(parts[0]+TAB+parts[1]);
}
}
fubaiAllArrayList = new ArrayList<String>();
Path fubai_all_path = new Path("/personal/zhoujie/recommend/fubaiall.csv");//14 15年全年购买过服百的全部用户名单
if (fs.exists(fubai_all_path)) {
in = fs.open(fubai_all_path);
reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
while ((tempString = reader.readLine()) != null) {
//年份 cust_id 服百事业部总和
String parts[] = tempString.split(TAB, -1);
if(parts.length!=3)continue;
fubaiAllArrayList.add(parts[0]+TAB+parts[1]);
}
}
fubaiArrayList = new ArrayList<String>();
Path fubai_path = new Path("/personal/zhoujie/recommend/fubaiall.csv");//14 15年全年购买过各服百事业部的全部用户名单
if (fs.exists(fubai_path)) {
in = fs.open(fubai_path);
reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
while ((tempString = reader.readLine()) != null) {
//年份 cust_id 各服百事业部
String parts[] = tempString.split(TAB, -1);
if(parts.length!=3)continue;
fubaiArrayList.add(parts[0]+TAB+parts[1]);
}
}
allArrayList = new ArrayList<String>();
Path all_path = new Path("/personal/zhoujie/recommend/all_order.csv");//14 15年全年下单用户
if (fs.exists(all_path)) {
in = fs.open(all_path);
reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
while ((tempString = reader.readLine()) != null) {
//年份 cust_id 事业部
String parts[] = tempString.split(TAB, -1);
if(parts.length!=3)continue;
allArrayList.add(parts[0]+TAB+parts[1]);
}
}
}
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
InputSplit inputSplit = context.getInputSplit();
String fileName = ((FileSplit) inputSplit).getPath().toString();
if(fileName.contains("/personal/zhoujie/recommend/orderdetail/")){
//date+TAB+app_id+TAB+permanentid+TAB+toProductid "APP全站" "服百事业部" order_id 单价 个数 cust_id
String[] splited = value.toString().split(TAB, -1);
if(splited.length!=10)return;
String year = splited[0].substring(0, 4);
String cust_id = splited[9];
String department = splited[5];
if("2015".equals(year)){
if("服百事业部总和".equals(department)){//全部服百事业部
if (fubaiAllArrayList.contains("2014"+TAB+cust_id)) {//说明14年在服百事业部买过,作为老用户
context.write(new Text("2015"+TAB+"服百事业部总和"+TAB+"老用户"), new Text(cust_id));
}else if(bookArrayList.contains("2014"+TAB+cust_id)){//说明14年在图书事业部买过,作为新用户-转化用户
context.write(new Text("2015"+TAB+"服百事业部总和"+TAB+"新用户-转化用户"), new Text(cust_id));
}else if(!allArrayList.contains("2014"+TAB+cust_id)){//说明在14年没有买过任何东西
context.write(new Text("2015"+TAB+"服百事业部总和"+TAB+"新用户-新增用户"), new Text(cust_id));
}
}else {//各服百事业部
if (fubaiArrayList.contains("2014"+TAB+cust_id)) {//说明14年在子服百事业部买过,作为老用户
context.write(new Text("2015"+TAB+department+TAB+"老用户"), new Text(cust_id));
}else if(bookArrayList.contains("2014"+TAB+cust_id)){//说明14年在图书事业部买过,作为新用户-转化用户
context.write(new Text("2015"+TAB+department+TAB+"新用户-转化用户"), new Text(cust_id));
}else if(!allArrayList.contains("2014"+TAB+cust_id)){//说明在14年没有买过任何东西
context.write(new Text("2015"+TAB+department+TAB+"新用户-新增用户"), new Text(cust_id));
}
}
}else if ("2016".equals(year)) {
if("服百事业部总和".equals(department)){//全部服百事业部
if (fubaiAllArrayList.contains("2015"+TAB+cust_id)) {//说明15年在服百事业部买过,作为老用户
context.write(new Text("2016"+TAB+"服百事业部总和"+TAB+"老用户"), new Text(cust_id));
}else if(bookArrayList.contains("2015"+TAB+cust_id)){//说明15年在图书事业部买过,作为新用户-转化用户
context.write(new Text("2016"+TAB+"服百事业部总和"+TAB+"新用户-转化用户"), new Text(cust_id));
}else if(!allArrayList.contains("2015"+TAB+cust_id)){//说明在15年没有买过任何东西
context.write(new Text("2016"+TAB+"服百事业部总和"+TAB+"新用户-新增用户"), new Text(cust_id));
}
}else {//各服百事业部
if (fubaiArrayList.contains("2015"+TAB+cust_id)) {//说明15年在子服百事业部买过,作为老用户
context.write(new Text("2016"+TAB+department+TAB+"老用户"), new Text(cust_id));
}else if(bookArrayList.contains("2015"+TAB+cust_id)){//说明15年在图书事业部买过,作为新用户-转化用户
context.write(new Text("2016"+TAB+department+TAB+"新用户-转化用户"), new Text(cust_id));
}else if(!allArrayList.contains("2015"+TAB+cust_id)){//说明在15年没有买过任何东西
context.write(new Text("2016"+TAB+department+TAB+"新用户-新增用户"), new Text(cust_id));
}
}
}
}
}
}
一、JDK集合类
不用说,这个不是我们今天介绍的重点。正是由于原始集合的效率低下才有了这篇文章的存在。即上述代码就是JDK集合类的实现代码,经过多次测试,作业消耗时间大概在三个小时作业。
二、FastUtil集合框架
经过测试,FastUtil的集合类替换原始集合的时候,用时两小时:
bookArrayList = new ObjectBigArrayBigList<String>()
三、HPPC集合框架
经过测试,FastUtil的集合类替换原始集合的时候,用时三分钟:
bookArrayList = new ObjectHashSet<String>()
好快!
经过这三个集合类的测试,发现HPPC集合框架的查询效率是最高的。
Java开发中各种集合框架简介的更多相关文章
- 吴裕雄--天生自然 JAVA开发学习:集合框架
import java.util.*; public class Test{ public static void main(String[] args) { List<String> l ...
- Java中的集合框架(上)
Java中的集合框架概述 集合的概念: Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象. 集合的作用: 1.在类的内部,对数据进行组织: 2.简单的快速的搜索大数据量的 ...
- Java中的集合框架-Collection(一)
一,Collection接口 在日常的开发工作中,我们经常使用数组,但是数组是有很多的局限性的,比如:数组大小固定后不可修改,只能存储基本类型的值等等. 基于数组的这些局限性,Java框架就产生了用于 ...
- Java中的集合框架-Collections和Arrays
上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...
- Java中的集合框架-Map
前两篇<Java中的集合框架-Commection(一)>和<Java中的集合框架-Commection(二)>把集合框架中的Collection开发常用知识点作了一下记录,从 ...
- 菜鸟日记之 java中的集合框架
java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterat ...
- Java中的集合框架-Collection(二)
上一篇<Java中的集合框架-Collection(一)>把Java集合框架中的Collection与List及其常用实现类的功能大致记录了一下,本篇接着记录Collection的另一个子 ...
- JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...
- JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...
随机推荐
- mysql的主主复制详解
Mysql双主部署 解释: 所谓双主备份,其实也就是互做主从复制,每台master既是master,又是另一台服务器的slave.这样,任何一方所做的变更,都会通过复制应用到另外一方的数据库中. 要求 ...
- ZooKeeper客户端 zkCli.sh 节点的增删改查
zkCli.sh 在 bin 目录下的 zkCli.sh 就是ZooKeeper客户端 ./zkCli.sh -timeout 5000 -server 127.0.0.1:2181 客户端与 ...
- solr 字段设置不存储表示不会进行分词
solr 字段设置不存储表示不会进行分词
- python 模块之-sys
python 模块 sys import sys sys.argv # 参数,第一个参数是脚本的文件明,自定义参数为数组的第二个 sys.argv[1] sys.version # ...
- 关于mysql的压测sysbench
测试表格:CREATE TABLE `sbtest` ( `id` int(10) unsigned NOT NULL auto_increment, `k` int(10) unsigned NOT ...
- Zabbix3.0学习笔记
第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源 网站/服务器 的可用性 1.1.1 网站可用性 在软件系统的高可靠性(也 ...
- Dumb Bones UVA - 10529(概率dp)
题意: 你试图把一些多米诺骨牌排成直线,然后推倒它们.但是如果你在放骨牌的时候不小心把刚放的骨牌碰倒了,它就会把相临的一串骨牌全都碰倒, 而你的工作也被部分的破坏了. 比如你已经把骨牌摆成了DD__D ...
- 12 Zabbix Item类型之Zabbix JMX类型
点击返回:自学Zabbix之路 12 Zabbix Item类型之Zabbix JMX类型 JMX 全称是Java Management Extensions,即Java管理扩展.Java程序会开放一 ...
- CodeForces 1110F Nearest Leaf | 线段树/换根
我--又诈尸了-- 代码几乎都不会写了,打场CF居然上分啦,开心!(虽然还是比不过列表里的各路神仙) 题目链接 题目描述 一棵\(n\)个点的有根树,规定一种dfs序(规则:编号小的点优先dfs),\ ...
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...