我收到了這個作業測驗任務,但我的解決方案被拒絕了。請給我一個提示,什么是解決此任務的最佳方法。
我后來發現,他們希望我使用 Java 8 的特性。
/**
* Marking will be based upon producing a readable, well engineered solution rather than factors
* such as speed of processing or other performance-based optimizations, which are less
* important.
*
*
* The Date sorter interface, implement the single method
* within this interface.
*/
public interface IDateSorter {
/**
* The implementation of this method should sort dates.
* The output should be in the following order:
* Dates with an 'r' in the month,
* sorted ascending (first to last),
* then dates without an 'r' in the month,
* sorted descending (last to first).
* For example, October dates would come before May dates,
* because October has an 'r' in it.
* thus: (2005-07-01, 2005-01-02, 2005-01-01, 2005-05-03)
* would sort to
* (2005-01-01, 2005-01-02, 2005-07-01, 2005-05-03)
*
* @param unsortedDates - an unsorted list of dates
* @return the collection of dates now sorted as per the spec
*/
Collection<LocalDate> sortDates(List<LocalDate> unsortedDates);
}
這是我的解決方案。
@Override
public Collection<LocalDate> sortDates(List<LocalDate> unsortedDates) {
List<LocalDate> listWithR = new ArrayList<>();
List<LocalDate> listWithOutR = new ArrayList<>();
//Separate unsortedDates in to list depends on 'R' factor
for (LocalDate date: unsortedDates) {
if (date.getMonth().getValue() < 5 || date.getMonth().getValue() > 8) {
listWithR.add(date);
} else {
listWithOutR.add(date);
}
}
//Sort list with R
Collections.sort(listWithR);
//Sort list without R
listWithOutR.sort(Comparator.reverseOrder());
//Adding list without R to list with R
listWithR.addAll(listWithOutR);
return listWithR;
}
uj5u.com熱心網友回復:
給定的串列可以根據需要一次性排序,而無需將其分成兩部分(并根據需要使用 Java 8 函式式編程特性)。
使用 Java 8 創建比較器
該方法歸結為定義適當的Comparator.
為此,我們可以使用Comparator介面的 Java 8 靜態方法,例如Comparator.comparing().
第一部分根據月份名稱對日期進行分組,可描述如下:
Comparator.comparing(ld -> !ld.getMonth().name().contains("R"))
提醒:值的自然順序是-> ,因此條件被否定。booleanfalsetrue
我們需要在 Comparator 的第二部分檢查相同的條件(因為這些日期組應該以不同的方式排序),因此定義 a 是有意義的Predicate:
public static final Predicate<LocalDate> HAS_NO_R = ld -> !ld.getMonth().name().contains("R");
第一部分將簡化為:
Comparator.comparing(HAS_NO_R::test)
為了強加所需的升序和降序,我們可以使用ChronoLocalDate.toEpochDay(),從 epoch 回傳天數作為long,與 結合使用Comparator.thenComparingLong()。
為了使"R"名稱中沒有的日期組按降序排序,紀元計數通過乘以來反轉(-1)。
thenComparingLong(ld -> HAS_NO_R.test(ld) ? (-1) * ld.toEpochDay() : ld.toEpochDay())
完成實施
現在讓我們把所有的部分放在一起。
Comparator Predicate:
public static final Predicate<LocalDate> HAS_NO_R = ld -> !ld.getMonth().name().contains("R");
public final Comparator<LocalDate> BY_MONTH_R_ASC_NO_R_DESC =
Comparator.comparing(HAS_NO_R::test)
.thenComparingLong(ld -> HAS_NO_R.test(ld) ?
(-1) * ld.toEpochDay() : ld.toEpochDay()
);
這是方法本身。我們可以使用 Stream API 來生成排序串列:
public static Collection<LocalDate> sortDates(List<LocalDate> unsortedDates) {
return unsortedDates.stream() // assumption that original list should not be mutated
.sorted(BY_MONTH_R_ASC_NO_R_DESC)
.toList();
}
注意:對于該方法是否應該回傳一個新 Collection的. 我做了一個安全的假設,即不應改變原始串列。
出于完整性的目的,原始串列可以使用 Java 9 進行排序List.sort():
unsortedDates.sort(BY_MONTH_R_ASC_NO_R_DESC);
return unsortedDates;
main()
public static void main(String[] args) {
List<LocalDate> dates = List.of(
LocalDate.parse("2005-07-01"), LocalDate.parse("2005-01-02"),
LocalDate.parse("2005-01-01"), LocalDate.parse("2005-05-03")
);
sortDates(dates).forEach(System.out::println);
}
輸出:
2005-01-01
2005-01-02
2005-07-01
2005-05-03
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/522662.html
