插入1000w条记录到文本文件并读取做分组排序

背景

某司线上笔试题

随机生成 Salary {name, baseSalary, bonus }的记录,如“wxxx,10,1”,每行一条记录,总共1000万记录,写入文本文件(UFT-8编码),然后读取文件,name的前两个字符相同的,其年薪累加,比如wx,100万,3个人,最后做排序和分组,输出年薪总额最高的10组,并将其尽量优化到五秒

package subject.demo.two;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * @author cmai/nico
 * @createDate 2018/11/12
 * @description
 */
public class Application {

    static int append = 0;

    public static void main(String[] args) throws IOException, InterruptedException {
        //文件
        File file = new File("D:/demo2.txt");
        if (file.exists()) {
            file.delete();
            file.createNewFile();
        }
        FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
        BufferedWriter bw = new BufferedWriter(fw);

        long startTime = System.currentTimeMillis();

        //记录条数
        final int count = 10000000;
        final int batch = 1000;
        final int lop = count/batch;
        final CountDownLatch countDown = new CountDownLatch(lop);

        ThreadPoolExecutor service = new ThreadPoolExecutor(1000, 1000, 0, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
        for(int start = 0; start < lop; start ++) {
            service.execute(() -> {
                StringBuffer stringBuffer = new StringBuffer();
                for (int i=0; i < batch; i++){
                    stringBuffer.append(getRandomString(4) + "," +(int) (Math.random() * 9000 + 1000) + "," +(int) (Math.random() * 9000 + 1000));
                    stringBuffer.append("\r\n");
                }
                try {
                    synchronized (bw) {
                        bw.write(stringBuffer.toString());
                        bw.flush();
                        countDown.countDown();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
        countDown.await();
        bw.close();
        System.out.println("insert finish");

        FileReader reader = new FileReader(file);
        BufferedReader br = new BufferedReader(reader);
        String line = null;
        int c = 0;

        Map<String, Integer> map = new HashMap<>();
        Map<String,Long> countMap = new HashMap<>();

        int lineCount = 0;
        while((line = br.readLine()) != null) {
            final String[] infos = line.split("[,]");
            String start = infos[0].substring(0, 2);
            int yearSalary = Integer.parseInt(infos[1]) + Integer.parseInt(infos[2]);
            Integer s = map.get(start);
            if(s != null) {
                map.put(start, yearSalary + s);
                countMap.put(start,countMap.get(start)+1);
            }else {
                map.put(start, yearSalary);
                countMap.put(start,1L);
            }
            ++lineCount;
        }
        List<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
        Collections.sort(list, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));
        for (int i =0;i<10;i++){
            String key = list.get(i).getKey();
            System.out.println(key+","+list.get(i).getValue()+"万,"+countMap.get(key)+"人");
        }
        System.out.println("line:" + lineCount);
        System.out.println("耗时:" + (System.currentTimeMillis() - startTime) + " ms");
        service.shutdown();
    }

    public static String getRandomString(int length){
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<length;i++){
            int number=random.nextInt(5);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }
}


其实还是有点问题,当时比较仓促,其实分组和排序可以在插入的时候做,不用再读取一遍。
笔试通过了,去现场面试做了套笔试题滚蛋了 233…
感谢大表哥提供forkjoin的思路

猜你喜欢

转载自blog.csdn.net/qq_35902833/article/details/85064761