java 快速读文件_JAVA8快速写入和读取文件

JAVA8快速写入和读取文件?

话不多说,先看题:

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

​ wx, 200万,10人

​ lt, 180万,8人

​ ....

name 4位a-z随机,baseSalary [0,100]随机 bonus[0-5]随机 ,年薪总额 = baseSalary*13 + bonus。

思路:

第一步:先编写一个Salary对象

里面包含有name,baseSalary, bounus属性,然后编写一个构造器,重写toString()方法方便序列化数据,同时编写构建Salary对象的方法build();

/**

* name 4位a-z随机

* baseSalary 0-100随机

* bonus 0-5随机

* 年薪总额 = baseSalary * 13 + bonus

*/

class Salary {

// name 4位a-z随机,baseSalary 0-100随机,bonus 0-5随机 年薪总额 = 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随机数

this.baseSalary = (int)(100 * Math.random());

// 0-5随机数

this.bonus = (int)(5 * Math.random());

return this;

}

@Override

public String toString() {

return name + " " + baseSalary + " " + bonus;

}

/**

* 生产Name随机函数 4位a-z随机

* @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进行写入

/**

* NIO进行写入

* @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();

}

比较下来,单纯从这个代码的性能上讲差不太多!

第三步:读取并解析文件在进行排序

​ a) 通过JAVA的IO进行读取:

/**

* Java IO读取文件的方式

* @return

* @throws Exception

*/

public static List readFileIO() throws Exception {

File file = new File(FILE_NAME);

List list = new ArrayList<>();

InputStreamReader reader = new InputStreamReader(new FileInputStream(file)); // 建立一个输入流对象reader

BufferedReader br = new BufferedReader(reader); // 建立一个对象,它把文件内容转成计算机能读懂的语言

String line = ""; // 每一行的内容

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]))); // 添加一个Salary实体

i++;

}

reader.close();

br.close();

return list;

}

​ b) 通过JAVA的NIO读取:

/**

* JDK8 NIO读取文件

* @return

* @throws Exception

*/

public static List readFileNIO() throws Exception {

List 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]))); // 添加一个Salary实体

});

return list;

}

二者比较下来:使用jdk1.8读取更简单,效率性能更高!

第四步:使用JDK8的Stream进行排序和截取

/**

* 排序并获取前十数据

* @param salaries

*/

public static void sort(List salaries) {

Map result = new HashMap<>();

salaries.forEach(salary -> {

String shortName = salary.getName().substring(0, 2);

GroupSalary groupSalary = null;

List 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 r = result.entrySet().stream()

.sorted((Map.Entry o1, Map.Entry 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());

});

}

同时将数据封装在GroupSalary中

class GroupSalary {

private List salaries;

private String shortName;

private int total;

public List getSalaries() {

return salaries;

}

public void setSalaries(List 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数据基本上1分钟不到就可以完成写入和读取,欢迎大家进行改写和优化,具体代码请去:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值