首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面试问题-使用Java 8特性划分和排序LocalDate对象

面试问题-使用Java 8特性划分和排序LocalDate对象
EN

Stack Overflow用户
提问于 2022-10-27 16:30:16
回答 1查看 88关注 0票数 1

我收到了这份工作的测试任务,但基于我的解决方案我被拒绝了.请给我一个提示什么是最好的方式来解决这个任务。

正如我稍后发现的,他们希望我使用Java 8特性。

代码语言:javascript
复制
/**
 * 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);
}

这是我的解决方案。

代码语言:javascript
复制
@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;

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-27 17:12:19

可以根据需要对给定的列表进行排序,在一次中进行排序,而无需将其分成两部分(并根据需要使用Java8函数编程特性)。

用Java 8创建比较器

这种方法归结为定义适当的Comparator

为此,我们可以使用Comparator接口的Java8静态方法,比如Comparator.comparing()

根据月份名称对日期进行分组的第一部分可以描述如下:

代码语言:javascript
复制
Comparator.comparing(ld -> !ld.getMonth().name().contains("R"))

提醒: boolean值的自然顺序是false -> true,因此条件被否定。

我们需要在比较器的第二部分检查相同的条件(因为这些日期组的排序应该不同),因此定义一个Predicate是有意义的。

代码语言:javascript
复制
public static final Predicate<LocalDate> HAS_NO_R = ld -> !ld.getMonth().name().contains("R");

第一部分将简化为:

代码语言:javascript
复制
Comparator.comparing(HAS_NO_R::test)

为了强制执行所需的升序和降序,我们可以使用ChronoLocalDate.toEpochDay(),将从纪元到long的天数与Comparator.thenComparingLong()一起返回。

为了使名称中没有"R"的日期组按降序排序,时代计数通过乘以(-1)来逆转。

代码语言:javascript
复制
thenComparingLong(ld -> HAS_NO_R.test(ld) ? (-1) * ld.toEpochDay() : ld.toEpochDay())

完全实施

现在,让我们把所有的片段放在一起。

Comparator + Predicate

代码语言:javascript
复制
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生成排序列表:

代码语言:javascript
复制
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()对原始列表进行排序

代码语言:javascript
复制
unsortedDates.sort(BY_MONTH_R_ASC_NO_R_DESC);

return unsortedDates;

main()

代码语言:javascript
复制
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);
}

输出:

代码语言:javascript
复制
2005-01-01
2005-01-02
2005-07-01
2005-05-03
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74225376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档