摘要:快速寫入和讀取文件話不多說,先看題隨機生成的記錄,如,每行一條記錄,總共萬記錄,寫入文本文件編碼,然后讀取文件,的前兩個字符相同的,其年薪累加,比如,萬,個人,最后做排序和分組,輸出年薪總額最高的組萬,人萬,人位隨機,隨機隨機,年薪總
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() + "
");
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("
");
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分鐘不到就可以完成寫入和讀取,歡迎大家進行改寫和優化,具體代碼請去:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/72504.html
摘要:示例字符串數值算術和文件原文譯者飛龍協議大量的教程和文章都涉及到中最重要的改變,例如表達式和函數式數據流。不僅僅是字符串,正則表達式模式串也能受益于數據流。 Java 8 API 示例:字符串、數值、算術和文件 原文:Java 8 API by Example: Strings, Numbers, Math and Files 譯者:飛龍 協議:CC BY-NC-SA 4.0 ...
摘要:基本輸入流輸入流類中包含兩類功能輸入流的兩大功能讀取流中字節數據的功能是通過方法來完成。基本輸出流與類相對應的類表示基本的輸出流,用來把數據從程序輸出到其他地方。 一堆廢話(趕快跳過) 在我們的日常開發中 I/O 涉及到我們開發的方方面面,雖然早在 JDK1.5 就新增了 NIO的概念,但是 java.io 的使用以及技巧在我們的日常開發中還是占據很高的比重。 概念(不看也行) ...
摘要:實戰讀書筆記第一章從方法傳遞到接著上次的,繼續來了解一下,如果繼續簡化代碼。去掉并且生成的數字是萬,所消耗的時間循序流并行流至于為什么有時候并行流效率比循序流還低,這個以后的文章會解釋。 《Java8實戰》-讀書筆記第一章(02) 從方法傳遞到Lambda 接著上次的Predicate,繼續來了解一下,如果繼續簡化代碼。 把方法作為值來傳遞雖然很有用,但是要是有很多類似與isHeavy...
摘要:提升自己,方便他人。其實一份文檔,說到底是為自己減輕工作量。總結總結起來,我們在提供一個通用包的時候,應該考慮以下七個點文檔。支持的類反射獲取參數名面向接口編程。一個注解,快速整合 聲明:本文屬原創文章,首發于公號程序員自學之道,轉載請注明出處 遇到槽點 開發實踐中,對于開發一個 jar 包,很多人都只是完成功能,只要功能使用沒問題,就算是完事了,但其實遠遠不夠。當用戶使用 jar 包...
摘要:和之間存在單向一對一關系,即通過指定的,總能找到唯一的確定的。從中取出數據時,只要給出指定的,就可以取出對應的。有時也稱為字典,或關聯數組。采用定制排序時不要求的實現接口中判斷兩個相等的標準是兩個通過方法返回,即認為這兩個是相等的。 map用于保存具有映射關系的數據,因此Map集合里保存著兩組值,一組值用于保存Map里的key,另外一組值用于保存Map里的value,key和value...
閱讀 2869·2021-07-30 15:30
閱讀 563·2019-08-30 15:55
閱讀 1631·2019-08-26 17:04
閱讀 642·2019-08-26 11:36
閱讀 2084·2019-08-26 10:58
閱讀 3563·2019-08-23 14:34
閱讀 1567·2019-08-22 18:48
閱讀 2535·2019-08-21 17:51