为了账号安全,请及时绑定邮箱和手机立即绑定

.net list group by in java 8?

.net list group by in java 8?

C#
芜湖不芜 2022-08-20 17:07:45
我得到了一个将代码从C#迁移到java 8的任务。我对下面的C#代码有问题。List<Log> lst = LogRepository.GetLogs(DateTime.Now.AddDays(-2), DateTime.Now);return lst.GroupBy(x => new { x.Title, x.ID }).Select(x => x.OrderByDescending(y => y.DataChangeTime).FirstOrDefault()).ToList();是的,方法GroupBy很容易,我知道它在做什么。但是,我无法弄清楚这个系列方法在做什么,它会返回什么结果?最后,任何人都可以给我一个java版本解决方案吗?
查看完整描述

1 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

C#代码已经由@Rango解释过了。假设 C 中的 -类采用以下设计#Log


class Log

{

    public String title;

    public String ID;

    public DateTime dataChangeTime;

    public String whatever;

    ...

}

和类似的Java类(例如 而不是 ),提供相同结果的 Java 表达式是:LocalDateTimeDateTime


Comparator<Log> comparator = (Log l1, Log l2) -> l2.dataChangeTime.compareTo(l1.dataChangeTime);    // sort descending

List<Log> resultantList = initialList.stream()

    .collect(Collectors.groupingBy(l -> l.title + l.ID)).values().stream()                          // group according to title and id

    .map(logs -> logs.stream().sorted(comparator).findFirst().get())                                // sort and take the first

    .collect(Collectors.toList());                                                                  // create the list

表达式将所有具有相同标题和 ID 的对象组合在一起,即 相同的值 。如果分组条件更复杂,那么定义一个表示分组的类可能更有意义,例如Logl.title + l.ID


class LogGroup {


    private String Title;

    private String ID;


    public LogGroup(String Title, String ID) {

        this.Title = Title;

        this.ID = ID;

    }


    @Override

    public boolean equals(Object o) {


        if (o == this) return true;

        if (!(o instanceof LogGroup)) {

            return false;

        }

        LogGroup logGroup = (LogGroup) o;

        return Objects.equals(Title, logGroup.Title) &&

               Objects.equals(ID, logGroup.ID);

    }


    @Override

    public int hashCode() {

        return Objects.hash(Title, ID);

    }

}

至关重要的是,类同时实现 - 和 -方法(即仅实现 -方法是不够的)。equalshashCodeequals


使用该类,Java 表达式将变为:


Comparator<Log> comparator = (Log l1, Log l2) -> l2.dataChangeTime.compareTo(l1.dataChangeTime);

List<Log> resultantList = initialList.stream()

    .collect(Collectors.groupingBy(l -> new LogGroup(l.title, l.ID))).values().stream()

    .map(logs -> logs.stream().sorted(comparator).findFirst().get())

    .collect(Collectors.toList());

像这样的列表


private static List<Log> getInitialList() {

    List<Log> initialList = new ArrayList<>();

    initialList.add(new Log("Title 6", "ID 6", LocalDateTime.of(2017,  1, 18, 23, 15, 12), "A"));

    initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2005,  4, 20, 16, 10, 10), "B"));

    initialList.add(new Log("Title 1", "ID 1", LocalDateTime.of(2010, 10, 25,  3,  5,  2), "C"));

    initialList.add(new Log("Title 2", "ID 2", LocalDateTime.of(2018,  2, 18, 21, 13, 32), "D"));

    initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2016,  5, 16, 15, 23, 15), "E"));

    initialList.add(new Log("Title 1", "ID 1", LocalDateTime.of(2012,  2,  8, 14, 46, 28), "F"));

    initialList.add(new Log("Title 6", "ID 6", LocalDateTime.of(1996,  1, 28, 22, 26, 34), "G"));

    initialList.add(new Log("Title 3", "ID 3", LocalDateTime.of(2007,  4, 15,  2,  5, 55), "H"));

    initialList.add(new Log("Title 6", "ID 3", LocalDateTime.of(2018,  1, 15, 20, 15, 10), "I"));

   return initialList;

}

由两个表达式处理,如下所示


Title 1    ID 1    2012-02-08 14:46:28    F

Title 3    ID 3    2016-05-16 15:23:15    E

Title 2    ID 2    2018-02-18 21:13:32    D

Title 6    ID 6    2017-01-18 23:15:12    A

Title 6    ID 3    2018-01-15 20:15:10    I

生成的列表本身没有排序(这很容易实现),但这也适用于 C#输出。Collections.sort(...)


查看完整回答
反对 回复 2022-08-20
  • 1 回答
  • 0 关注
  • 126 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信