我需要实现这个方法:
public Collector<CourseResult, ?, String> printableStringCollector() {
返回一个
Collector
,形成特殊的可打印 String
,如下所述。
它是多行
String
,包含所有结果、总值和分数的格式化表格。
表格的格式应满足以下要求:
到目前为止我写了这段代码:
public Collector<CourseResult, ?, String> printableStringCollector() {
return Collector.of(
StringBuilder::new,
(sb, courseResult) -> {
Person person = courseResult.getPerson();
Map<String, Integer> taskResults = courseResult.getTaskResults();
List<String> taskNames = taskResults.keySet().stream().sorted().collect(Collectors.toList());
// Calculate the total score and average mark
int totalScore = taskResults.values().stream().reduce(0, Integer::sum);
double averageMark = (double) totalScore / taskResults.size();
// Append the formatted row to the StringBuilder
sb.append(String.format("%-16s", person.getLastName() + " " + person.getFirstName()));
for (String taskName : taskNames) {
sb.append(String.format("|%-12s", taskResults.getOrDefault(taskName, 0)));
}
sb.append(String.format("|%-10.2f|%-5s|\n", averageMark, calculateMark(averageMark)));
},
// Combiner: Combine two StringBuilders by concatenating their contents
(sb1, sb2) -> sb1.append(sb2.toString()),
// Finisher: Return the final formatted table string
StringBuilder::toString);
}
private String calculateMark(double avg) {
return avg > 90 ? "A"
: avg >= 83 ? "B"
: avg >= 75 ? "C"
: avg >= 68 ? "D"
: avg >= 60 ? "E"
: "F";
}
如何添加带有字符串“Student”和任务名称的标题?
示例:
Student........|Phalaxing |Shieldwalling |Tercioing |Wedging |Total |Mark |
Eco Betty......|0 ........|83............|89........|59......|57.75 |F ...|
Lodbrok Johnny |61 .......|92............|67........|0.......|55.00 |F....|
Paige Umberto..|75....... |94............|0.........|52......|55.25 |F....|
Average........|45.55.... |89.67.........|52.00.....|37.00...|56.00 |F....|
@Ksenia,在“Finisher”功能中,而不是这个
// Finisher: Return the final formatted table string
StringBuilder::toString);
你可以实现任何类型的逻辑...
// Finisher: Return the final formatted table string
sb -> {
StringBuilder headerRow = new StringBuilder();
// Build the header in headerRow with proper column widths using keys and task names
// E.g. Student........|Phalaxing |Shieldwalling |Tercioing |Wedging |Total |Mark |
sb.insert(0, headerRow); // This inserts the header at the first position in the string builder
// You may prepare the average row also similarly, and append at the end
StringBuilder avgRow = new StringBuilder();
// Build average row here
sb.append(avgRow);
return sb.toString();
});
此外,由于您必须正确格式化字符串,因此您必须首先找到所有列的最大长度。因此,您可能需要遍历 CourseResult 两次。一次从所有名称和任务名称中获取最大长度以确定长度。 这应该在调用
Collector.of()
之前完成。
因此,在 Combiner
和 Finisher
中,这些长度已经可用。