我有教科书中的代码来打印日历的月份。它在该月第一天之前的所有日子打印空白,但在该月最后一天之后不打印空白。尽管代码工作正常,但问题是很难对其进行自动化测试并在不破坏它的情况下进行任何更新。
我想让这段代码易于测试。我想将日历月份移至类似数据结构的表中,并将打印逻辑移至单独的方法中。即,将数据和格式分开。
除了二维数组或自定义类之外,我还可以使用哪种数据结构/DS 来表示表?我更喜欢已经包含在 Java 中的 DS,或者来自流行且维护良好的库的 DS。理想情况下,DS 应该允许我 (1) 获取日期发生的日期(直接,而不是通过顺序迭代),以及 (2) 获取任何行并迭代它。
我无法从 here 得到答案。我不喜欢使用实用方法创建自己的 DS,除非别无选择。请指教。
Mon Tue Wed Thu Fri Sat Sun
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
代码:
import java.time.DayOfWeek;
import java.time.LocalDate;
//TODO : Add tests.
public class Calendar {
public static void main(String[] args) {
printCalendar(3, 2020);
}
public static void printCalendar(int month, int year) {
LocalDate date = LocalDate.of(year, month, 1);
System.out.println(" Mon Tue Wed Thu Fri Sat Sun");
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue(); // 1 = Monday, ... 7 = Sunday
for (int i = 1; i < value; i++) {
System.out.print(" ");
}
while (date.getMonthValue() == month) {
System.out.printf("%4d", date.getDayOfMonth());
date = date.plusDays(1);
if (date.getDayOfWeek().getValue() == 1) {
System.out.println();
}
}
if (date.getDayOfWeek().getValue() != 1) {
System.out.println();
}
}
//TESTS (for now)
/*
1 - Calendar should have exactly 7 columns.
2 - Header/top row should always be from Mon to Sun.
3 - 1st & last days of month should be in correct place.
4 - All days before 1st day of month should be empty.
*/
}
最佳答案
恕我直言,忘记使用 java.time
类进行渲染。
尝试这样的事情:
参加Day
类(class):
class Day {
int number;
String render() {
return number == 0 ? " " : String.format("%4d", number);
}
}
和一个Week
类:
class Week {
List<Day> days;
String render() {
return days.stream().map(Day::render).collect(Collectors.joining(""));
}
}
和一个Month
类:
class Month {
List<Week> weeks;
String render() {
return weeks.stream().map(Day::render).collect(
Collectors.joining("\n", " Mon Tue Wed Thu Fri Sat Sun", "\n")
);
}
}
对于“空白”天,不要指定数字。把你的日子变成几周,你的几周变成一个月,然后:
System.out.println(month.render());
关于java - 月份日历的数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60627560/