我想知道如何改进这个非常简单的代码。
代码非常冗长,两个forLoops绝对不是功能性的或简洁的。
我正在考虑使用Stream.iterate().limit(LAST_DAY_MONTH)
,但它不能解决我们需要返回值的问题。
public class WeekDaysPerMonth {
public Map getNumberWeekDaysPerMonth(int year) {
Map<Integer, Integer> weekDays = new Hashtable<>();
for (int monthCount = 1; monthCount <= 12; monthCount++) {
int daysCount = 0;
final int LAST_DAY_MONTH = getLastDayMonth(monthCount, year);
for (int day = 1; day <= LAST_DAY_MONTH; day++) {
final int weekDay = LocalDate.of(year, monthCount, day).getDayOfWeek().getValue();
daysCount = daysCount + (
(weekDay != DayOfWeek.SATURDAY.getValue()
&& weekDay != DayOfWeek.SUNDAY.getValue())
? 1 : 0);
}
weekDays.put(monthCount, daysCount);
}
return weekDays;
}
private int getLastDayMonth(int month, int year) {
final boolean yearBiSexto = (year % 4 ) == 0;
Map<Integer, Integer> lastDayMontMap = new HashMap<Integer, Integer>() {{
put(1, 31);
put(2, yearBiSexto ? 29 : 28);
put(3, 31);
put(4, 30);
put(5, 31);
put(6, 30);
put(7, 31);
put(8, 31);
put(9, 30);
put(10, 31);
put(11, 30);
put(12, 31);
}};
return lastDayMontMap.get(month);
}
这是我们提供2022年的结果。
mes : 1 - mes : 21
mes : 2 - mes : 20
mes : 3 - mes : 23
mes : 4 - mes : 21
mes : 5 - mes : 22
mes : 6 - mes : 22
mes : 7 - mes : 21
mes : 8 - mes : 23
mes : 9 - mes : 22
mes : 10 - mes : 21
mes : 11 - mes : 22
mes : 12 - mes : 22
拜托,任何改进都会很棒的!
发布于 2022-03-25 00:40:34
基于java.time Java 8的实现。
import java.time.DayOfWeek;
import java.time.Month;
import java.time.YearMonth;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Main {
public static void main(String args[]){
Map<String, Long> map = getNumberWeekDaysPerMonth(2022);
for (Map.Entry<String, Long> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue().toString());
}
}
public static Map<String, Long> getNumberWeekDaysPerMonth(int year) {
Map<String, Long> weekDays = new LinkedHashMap<>();
EnumSet<DayOfWeek> weekends = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );
Stream.of(Month.values()).forEach(month -> {
YearMonth yearMonth = YearMonth.of(year, month);
long countWeekDays = IntStream.rangeClosed(1, yearMonth.lengthOfMonth()).filter(day ->
!weekends.contains(yearMonth.atDay(day).getDayOfWeek())
).count();
weekDays.put(month.toString(), countWeekDays);
}
);
return weekDays;
}
}
输出:
JANUARY:21
FEBRUARY:20
MARCH:23
APRIL:21
MAY:22
JUNE:22
JULY:21
AUGUST:23
SEPTEMBER:22
OCTOBER:21
NOVEMBER:22
DECEMBER:22
YearMonth -是一个不可变的日期时间对象,表示一年和一个月的组合。
月份 -代表一年中的12个月
LocalDate.getDayOfWeek() -获取日期的每周一天。
编辑:聚集到一个流中,但前一个版本对于理解来说更加清晰。
public static Map<String, Long> getNumberWeekDaysPerMonth(int year) {
EnumSet<DayOfWeek> weekends = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );
return Stream.of(Month.values()).collect(Collectors.toMap(
Enum::toString,
month -> IntStream.rangeClosed(1, YearMonth.of(year, month).lengthOfMonth()).
filter(day -> !weekends.contains(LocalDate.of(year, month, day).getDayOfWeek())).
count(),
(e1, e2) -> e1,
LinkedHashMap::new));
}
https://stackoverflow.com/questions/71610627
复制相似问题