使用java处理海量数据,对数据进行分类聚合,以部分数据为例,对数据进行扩增得到海量数据。
张三 | 18 | 男 | 高三一班 |
李四 | 19 | 男 | 高三二班 |
张三 | 18 | 男 | 高三三班 |
张三 | 18 | 男 | 高三四班 |
张三 | 18 | 男 | 高三五班 |
李四 | 18 | 男 | 高三六班 |
李四 | 18 | 男 | 高三七班 |
李四 | 18 | 男 | 高三八班 |
李四 | 18 | 男 | 高三九班 |
李四 | 18 | 男 | 高三十班 |
使用IO流对数据进行扩增;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
//对文件数据扩增构成海量数据
public class Bigdata {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new FileReader("D:\\Java_Code\\src\\Originaldata.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\Java_Code\\src\\bigdata.txt"));
String str;
while((str=br.readline())!=null){
for(int i=0;i<=10000;i++){
bw.write(str);
bw.newLine();
}
br.close;
bw.close;
}
}
得到海量数据后使用两种方法对数据进行分类聚合;
1.使用传统的分类聚合方法(HashMap)的方法
public class demo_Tranditional {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader("D:\\Java_Code\\src\\bigdata.txt"));
HashMap<String, Integer> map = new HashMap<>();
String str;
while((str=br.readLine())!=null){
String clazz = str.split(",")[3];
if (map.containsKey(clazz)){
map.put(clazz,map.get(clazz)+1);
}else {
map.put(clazz,1);
}
}
br.close();
System.out.println(map);
}
}
利用传统的分类聚合的方法得到各个班级的人数;
2.使用多线程的方式优化分类聚合
思路:
1.对文件进行切分,分成8个子文件存储在本地
2.写线程类,写一个线程类,8个线程交叉执行
3.整合数据结果
1.对文件进行拆分
public class Demo02_SliptFile1 {
public static void main(String[] args) throws Exception {
long sum = lineNum();//总行数
int size=8;//拆分所少个文件
long fileRow = sum / size;//每个文件的行数
BufferedReader br = new BufferedReader(
new FileReader("D:\\Java_Code\\src\\bigdata.txt"));
int fileFlag=0;//写了多少文件
BufferedWriter bw = new BufferedWriter(
new FileWriter("D:\\Java_Code\\src\\data\\student-"+fileFlag));
long flag=0;
String line;
while ((line=br.readLine())!=null){
flag++;
if(flag>fileRow){//写入文件时,每一个文件写入的行数小于fileRow
bw.flush();
bw.close();
fileFlag++;
bw = new BufferedWriter(
new FileWriter("D:\\Java_Code\\src\\data\\student-"+fileFlag));
flag=0;
}
bw.write(line);
bw.newLine();
}
br.close();
}
}
//统计行数拆分小文件
public static long lineNum(){
BufferedReader br = new BufferedReader(
new FileReader("D:\\Java_Code\\src\\bigdata.txt"));
String line;
long sum=0;
while ((line=br.readLine())!=null){
sum++;
}
br.close();
return sum;
}
}
2.编写线程类:
public class MapTask extends Thread{
private int flag;
private File file;
public MapTask(){}
public MapTask(File file,int flag){
this.flag=flag;
this.file=file;
}
@Override
public void run(){
try {
BufferedReader br = new BufferedReader(
new FileReader(file.getAbsolutePath()));
HashMap<String, Integer> map = new HashMap<>();
String line;
while ((line=br.readLine())!=null){
String[] split = line.split(",");
if(split.length==4){
String clazz = split[3];
//分类聚合
if(map.containsKey(clazz)){
map.put(clazz,map.get(clazz)+1);
}else {
map.put(clazz,1);
}
}
}
System.out.println(map);
//把结果写入到文件中
BufferedWriter bw = new BufferedWriter(
new FileWriter("D:\\Java_Code\\src\\分类聚合\\BigData\\JieguoData\\part-"+flag));
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
Integer value = entry.getValue();
String s=key+":"+value;
bw.write(s);
bw.newLine();
}
bw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
实现线程类
public class Demo03_Map2 {
public static void main(String[] args) throws InterruptedException {
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(8);
File file = new File("D:\\Java_Code\\src\\分类聚合\\BigData\\data");
File[] files = file.listFiles();
int flag=0;
for (File file1 : files) {//获取切分后的小文件 8
//创建线程对象
MapTask mapTask = new MapTask(file1,flag);
//启动线程
pool.submit(mapTask);
flag++;
}
//关闭线程池
pool.shutdown();
pool.awaitTermination(100000l,TimeUnit.SECONDS);
}
}
3.对数据进行整合
public class Demo04_Reduce3 {
public static void main(String[] args) throws Exception{
HashMap<String, Integer> map = new HashMap<>();
File file = new File("D:\\Java_Code\\src\\分类聚合\\BigData\\JieguoData");
File[] files = file.listFiles();
for (File file1 : files) {
BufferedReader br = new BufferedReader(new FileReader(file1.getAbsolutePath()));
String line;
while ((line=br.readLine())!=null){
String[] split = line.split(":");
String clazz = split[0];
Integer num = Integer.valueOf(split[1]);
if(map.containsKey(clazz)){
map.put(clazz,map.get(clazz)+num);
}else {
map.put(clazz,num);
}
}
br.close();
}
System.out.println(map);
}
}
运行得到结果,在较少数据的情况下传统的分类聚合方法效率更高,在数据量较大的情况下,多线程共同处理海量数据效率更高。