JAVA对于数据分类聚合

使用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);
    }
}

运行得到结果,在较少数据的情况下传统的分类聚合方法效率更高,在数据量较大的情况下,多线程共同处理海量数据效率更高。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值