【碼歌】JAVA8實(shí)用——快速寫入和讀取文件

Java8快速讀取和寫入文件.png

話不多說(shuō)企蹭,先看題:

隨機(jī)生成 Salary {name, baseSalary, bonus }的記錄雳攘,如“wxxx,10,1”谎倔,每行一條記錄沥邻,總共1000萬(wàn)記錄服猪,寫入文本文件(UFT-8編碼)觉阅, 然后讀取文件甚颂,name的前兩個(gè)字符相同的用爪,其年薪累加顽照,比如wx无畔,100萬(wàn)宅粥,3個(gè)人参袱,最后做排序和分組,輸出年薪總額最高的10組:

wx 200萬(wàn) 10人
lt 180萬(wàn) 8人
... ... ...

name 4位a-z隨機(jī),baseSalary [0,100]隨機(jī) bonus[0-5]隨機(jī) 抹蚀,年薪總額 = baseSalary*13 + bonus剿牺。

思路:

第一步:先編寫一個(gè)Salary對(duì)象

里面包含有namebaseSalary, bounus屬性环壤,然后編寫一個(gè)構(gòu)造器晒来,重寫toString()方法方便序列化數(shù)據(jù),同時(shí)編寫構(gòu)建Salary對(duì)象的方法build()郑现;

/**
 *  name 4位a-z隨機(jī)
 *  baseSalary 0-100隨機(jī)
 *  bonus 0-5隨機(jī)
 *  年薪總額 = baseSalary * 13 + bonus
 */
class Salary {
    // name 4位a-z隨機(jī),baseSalary 0-100隨機(jī),bonus 0-5隨機(jī) 年薪總額 = baseSalary * 13 + bonus
    private String name;
    private int baseSalary;
    private int bonus;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getBaseSalary() {
        return baseSalary;
    }

    public void setBaseSalary(int baseSalary) {
        this.baseSalary = baseSalary;
    }

    public int getBonus() {
        return bonus;
    }

    public void setBonus(int bonus) {
        this.bonus = bonus;
    }


    public Salary() {

    }

    public Salary(String name, int baseSalary, int bonus) {
        this.name = name;
        this.baseSalary = baseSalary;
        this.bonus = bonus;
    }

    public Salary build() {
        this.name = getRandomName(4);
        // 0-100隨機(jī)數(shù)
        this.baseSalary = (int)(100 * Math.random());
        // 0-5隨機(jī)數(shù)
        this.bonus = (int)(5 * Math.random());
        return this;
    }

    @Override
    public String toString() {
        return name + " " + baseSalary + " " + bonus;
    }

    /**
     * 生產(chǎn)Name隨機(jī)函數(shù) 4位a-z隨機(jī)
     * @param length
     * @return
     */
    private static String getRandomName(int length ){
        String base = "abcdefghijklmnopqrstuvwxyz";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for ( int i = 0; i < length; i++ ){
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}

第二步:編寫寫入方法

? a) 第一種方式湃崩,使用Java的IO中BufferedWriter寫入文件

/**
 * 寫入文件
 * @return
 * @throws IOException
 */
public static File writeBuffer() throws IOException {
    File file = new File(FILE_NAME);
    FileOutputStream fos = new FileOutputStream(file);
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos));
    int i = AMOUNT;
    while(i > 0) {
        Salary salary = new Salary().build();
        writer.write(salary.toString() + "\r\n");
        i --;
    }
    writer.close();
    fos.close();
    return file;
}

? b) 第二種方式,使用JAVA的NIO中的FileChannel進(jìn)行寫入

/**
 * NIO進(jìn)行寫入
 * @throws IOException
 */
private static void writeNIO() throws IOException {
    FileOutputStream fos = new FileOutputStream(FILE_NAME, true);
    FileChannel channel = fos.getChannel();
    int i = AMOUNT;
    StringBuffer content = new StringBuffer();
    while(i > 0) {
        Salary salary = new Salary().build();
        content.append(salary.toString()).append("\r\n");
        i --;
    }
    ByteBuffer buf = ByteBuffer.wrap(content.toString().getBytes());
    buf.put(content.toString().getBytes());
    buf.flip();
    channel.write(buf);
    channel.close();
    fos.close();

}

比較下來(lái)接箫,單純從這個(gè)代碼的性能上講差不太多攒读!

第三步:讀取并解析文件在進(jìn)行排序

? a) 通過(guò)JAVA的IO進(jìn)行讀取:

/**
 * Java IO讀取文件的方式
 * @return
 * @throws Exception
 */
public static List<Salary> readFileIO() throws Exception {
    File file = new File(FILE_NAME);
    List<Salary> list = new ArrayList<>();
    InputStreamReader reader = new InputStreamReader(new FileInputStream(file)); // 建立一個(gè)輸入流對(duì)象reader
    BufferedReader br = new BufferedReader(reader); // 建立一個(gè)對(duì)象辛友,它把文件內(nèi)容轉(zhuǎn)成計(jì)算機(jī)能讀懂的語(yǔ)言
    String line = ""; // 每一行的內(nèi)容
    int i = 1;
    while ((line = br.readLine()) != null) {
        String[] split = line.trim().split(" ");// .trim()可以去掉首尾多余的空格
        list.add(new Salary(split[0], Integer.valueOf(split[1]), Integer.valueOf(split[2]))); // 添加一個(gè)Salary實(shí)體
        i++;
    }
    reader.close();
    br.close();
    return list;
}

? b) 通過(guò)JAVA的NIO讀缺”狻:

/**
 * JDK8 NIO讀取文件
 * @return
 * @throws Exception
 */
public static List<Salary> readFileNIO() throws Exception {
    List<Salary> list = new ArrayList<>();
    Files.lines(Paths.get(FILE_NAME)).forEach(line -> {
        String[] split = line.trim().split(" ");// .trim()可以去掉首尾多余的空格
        list.add(new Salary(split[0], Integer.valueOf(split[1]), Integer.valueOf(split[2]))); // 添加一個(gè)Salary實(shí)體
    });
    return list;
}

二者比較下來(lái):使用jdk1.8讀取更簡(jiǎn)單,效率性能更高瞎领!

第四步:使用JDK8的Stream進(jìn)行排序和截取

/**
 * 排序并獲取前十?dāng)?shù)據(jù)
 * @param salaries
 */
public static void sort(List<Salary> salaries) {
    Map<String, GroupSalary> result = new HashMap<>();
    salaries.forEach(salary -> {
        String shortName = salary.getName().substring(0, 2);
        GroupSalary groupSalary = null;
        List<Salary> salaryList = null;
        if (result.containsKey(shortName)) {
            groupSalary = result.get(shortName);
            salaryList = groupSalary.getSalaries();
        } else {
            groupSalary = new GroupSalary();
            salaryList = new ArrayList<>();
            groupSalary.setSalaries(salaryList);
        }
        salaryList.add(salary);
        groupSalary.setShortName(shortName);
        groupSalary.setTotal(groupSalary.getTotal() + salary.getBaseSalary() * 13 + salary.getBonus());
        result.put(shortName, groupSalary);
    });

    List<GroupSalary> r = result.entrySet().stream()
            .sorted((Map.Entry<String, GroupSalary> o1, Map.Entry<String, GroupSalary> o2) -> o2.getValue().getTotal() - o1.getValue().getTotal())
            .map(entry -> entry.getValue()).collect(Collectors.toList()).subList(0,10);

    r.forEach(groupSalary -> {
        System.out.println(groupSalary.getShortName() + " " + groupSalary.getTotal() + " " + groupSalary.getSalaries().size());
    });
}

同時(shí)將數(shù)據(jù)封裝在GroupSalary中

class GroupSalary {
    private List<Salary> salaries;
    private String shortName;
    private int total;

    public List<Salary> getSalaries() {
        return salaries;
    }

    public void setSalaries(List<Salary> salaries) {
        this.salaries = salaries;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }


}

到此如果寫入100W數(shù)據(jù)基本上1分鐘不到就可以完成寫入和讀取泌辫,歡迎大家進(jìn)行改寫和優(yōu)化随夸。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末九默,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宾毒,更是在濱河造成了極大的恐慌驼修,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诈铛,死亡現(xiàn)場(chǎng)離奇詭異乙各,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)幢竹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門耳峦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人焕毫,你說(shuō)我怎么就攤上這事蹲坷。” “怎么了邑飒?”我有些...
    開(kāi)封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵循签,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我疙咸,道長(zhǎng)县匠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮乞旦,結(jié)果婚禮上贼穆,老公的妹妹穿的比我還像新娘。我一直安慰自己兰粉,他們只是感情好扮惦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亲桦,像睡著了一般崖蜜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客峭,一...
    開(kāi)封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天豫领,我揣著相機(jī)與錄音,去河邊找鬼舔琅。 笑死等恐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的备蚓。 我是一名探鬼主播课蔬,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼郊尝!你這毒婦竟也來(lái)了二跋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤流昏,失蹤者是張志新(化名)和其女友劉穎扎即,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體况凉,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谚鄙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刁绒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闷营。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖知市,靈堂內(nèi)的尸體忽然破棺而出傻盟,到底是詐尸還是另有隱情,我是刑警寧澤初狰,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布莫杈,位于F島的核電站,受9級(jí)特大地震影響奢入,放射性物質(zhì)發(fā)生泄漏筝闹。R本人自食惡果不足惜媳叨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望关顷。 院中可真熱鬧糊秆,春花似錦、人聲如沸议双。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)平痰。三九已至汞舱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宗雇,已是汗流浹背昂芜。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赔蒲,地道東北人泌神。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像舞虱,于是被迫代替她去往敵國(guó)和親欢际。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理矾兜,服務(wù)發(fā)現(xiàn)损趋,斷路器,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • 2018-03-1 (稻盛哲學(xué)學(xué)習(xí)會(huì))打卡第25天 姓名:王燕君 部門:分水碶 組別:待定 【知~學(xué)習(xí)】 誦讀《活...
    王燕君分水碶閱讀 172評(píng)論 0 0
  • 字符串函數(shù)char_length(字符串)字符數(shù)length(字符串)字節(jié)數(shù)left(字符串焕刮,length)獲得左...
    ssttIsme閱讀 135評(píng)論 0 1
  • 學(xué)習(xí)感悟:愛(ài)上自己的工作舶沿,從工作中找樂(lè)趣墙杯,這樣就不會(huì)感覺(jué)到自己很累配并。 1、付出不亞于任何人的努力7分 2高镐、要謙虛不...
    管宏洋閱讀 148評(píng)論 0 0