如何使用 Streams 将 HashMap 中的数据按排序顺序写入文件
How to write the data from a HashMap into a file in Sorted order with Streams
我可以像这样从 HashMap
输出排序的条目:
public static void sortAverageTime(HashMap<String, Integer> noSortedMap) {
noSortedMap.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> System.out.println(x + "ms"));
}
但现在我需要将条目写入文件。我这样做:
try {
File file = new File("newfile.txt");
if (!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file, true);
averageTime.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> fw.write(x + "ms"));
fw.write("---" + currentDate + "\n");
fw.close();
}
显示错误:
Unhandled exception: java.io.IOException.
如何将排序后的条目从 HashMap
输出到 文件?
在将 fw.write(x + "ms");
写入文件时处理异常,请参见下面的代码。 FileWriter write 函数 thow IO 异常 你没有处理。
try {
File file = new File("newfile.txt");
if (!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file, true);
noSortedMap.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> {
try {
fw.write(x + "ms");
} catch (IOException e) {
e.printStackTrace();
}
});
fw.write("---" + new Date() + "\n");
fw.close();
}
catch (Exception e)
{
System.out.println("Exception occur emsg= "+w.getMessage());
}
像写入文件一样放置 IO-operations 不是一个好主意 因为 exception-handling 管道代码完全打败了 lambda 表达式的可读性。
在 Java 中引入函数编程的主要原因是提供更好的方法 构建代码,循环总是比 顺序流 .
更 性能
我建议分两步解决这个问题:首先,准备数据,然后将其写入文件。
准备数据需要:
- 排序地图内容;
- 将每个条目转换为
String
并添加 time-unit of "ms"
;
- 将排序后的数据收集到列表。
第一步可能如下所示:
public static List<String> getSortedData(Map<String, Integer> averageTime) {
return averageTime.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.map(entry -> String.format("%s %d %s", entry.getKey(), entry.getValue(), "ms"))
.collect(Collectors.toList());
}
正在写入文件(为了更好的性能,FileWriter
被包装成 BufferedWriter
)
public static void sortAverageTime(Map<String, Integer> averageTime,
String fileName) {
File file = new File(fileName);
if (!file.exists())
file.createNewFile();
List<String> sortedData = getSortedData(averageTime);
sortedData.add("---" + LocalDate.now()); // replacement for fw.write("---" + currentDate + "\n")
try(BufferedWriter writer = new BufferedWriter(new FileWriter(file, true))) {
for (String next: sortedData) {
writer.write(next);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
并且使用 Java NIO 第二步可以简化为:
public static void sortAverageTime(Map<String, Integer> averageTime,
String fileName) {
File file = new File(fileName);
if (!file.exists())
file.createNewFile();
List<String> sortedData = getSortedData(averageTime);
sortedData.add("---" + LocalDate.now());
try {
Files.write(file.toPath(), sortedData, StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
一些重要说明:
Never 关闭 try
块内的资源,如果发生异常,资源将永远不会被释放。为此,可以使用 try with resources(这是首选方式),在 finally
块中显式调用 close()
。
forEach()
操作的用法是 discouraged by the documentation 在有其他方法可以达到相同结果的情况下。所以从流写入文件的方法在所有方面都是不好:
- 它谴责 可读性;
- 它使您的方法 更少 narrow-focused 并且 更难测试 ;
- 它与文档不一致。
我可以像这样从 HashMap
输出排序的条目:
public static void sortAverageTime(HashMap<String, Integer> noSortedMap) {
noSortedMap.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> System.out.println(x + "ms"));
}
但现在我需要将条目写入文件。我这样做:
try {
File file = new File("newfile.txt");
if (!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file, true);
averageTime.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> fw.write(x + "ms"));
fw.write("---" + currentDate + "\n");
fw.close();
}
显示错误:
Unhandled exception: java.io.IOException.
如何将排序后的条目从 HashMap
输出到 文件?
在将 fw.write(x + "ms");
写入文件时处理异常,请参见下面的代码。 FileWriter write 函数 thow IO 异常 你没有处理。
try {
File file = new File("newfile.txt");
if (!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file, true);
noSortedMap.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEach(x -> {
try {
fw.write(x + "ms");
} catch (IOException e) {
e.printStackTrace();
}
});
fw.write("---" + new Date() + "\n");
fw.close();
}
catch (Exception e)
{
System.out.println("Exception occur emsg= "+w.getMessage());
}
像写入文件一样放置 IO-operations 不是一个好主意 因为 exception-handling 管道代码完全打败了 lambda 表达式的可读性。
在 Java 中引入函数编程的主要原因是提供更好的方法 构建代码,循环总是比 顺序流 .
更 性能我建议分两步解决这个问题:首先,准备数据,然后将其写入文件。
准备数据需要:
- 排序地图内容;
- 将每个条目转换为
String
并添加 time-unit of"ms"
; - 将排序后的数据收集到列表。
第一步可能如下所示:
public static List<String> getSortedData(Map<String, Integer> averageTime) {
return averageTime.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.map(entry -> String.format("%s %d %s", entry.getKey(), entry.getValue(), "ms"))
.collect(Collectors.toList());
}
正在写入文件(为了更好的性能,FileWriter
被包装成 BufferedWriter
)
public static void sortAverageTime(Map<String, Integer> averageTime,
String fileName) {
File file = new File(fileName);
if (!file.exists())
file.createNewFile();
List<String> sortedData = getSortedData(averageTime);
sortedData.add("---" + LocalDate.now()); // replacement for fw.write("---" + currentDate + "\n")
try(BufferedWriter writer = new BufferedWriter(new FileWriter(file, true))) {
for (String next: sortedData) {
writer.write(next);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
并且使用 Java NIO 第二步可以简化为:
public static void sortAverageTime(Map<String, Integer> averageTime,
String fileName) {
File file = new File(fileName);
if (!file.exists())
file.createNewFile();
List<String> sortedData = getSortedData(averageTime);
sortedData.add("---" + LocalDate.now());
try {
Files.write(file.toPath(), sortedData, StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
一些重要说明:
Never 关闭
try
块内的资源,如果发生异常,资源将永远不会被释放。为此,可以使用 try with resources(这是首选方式),在finally
块中显式调用close()
。forEach()
操作的用法是 discouraged by the documentation 在有其他方法可以达到相同结果的情况下。所以从流写入文件的方法在所有方面都是不好:- 它谴责 可读性;
- 它使您的方法 更少 narrow-focused 并且 更难测试 ;
- 它与文档不一致。