首页 > 解决方案 > 在 Java 中检索每个组的第一项

问题描述

在Java中,如何在按字段(/ s)分组后列出每个组的最新/第一项?例如,从给定的医疗记录列表中,如何检索每个患者的最新记录。

    样本数据
    -------------------------------------------------- -------------------------
    患者姓名 | 报告日期 | 阅读No | 测量
    -------------------------------------------------- -------------------------
    X | 2020-01-02 | 1 | 255
    是 | 2020-01-02 | 1 | 250
    X | 2020-01-02 | 2 | 266
    是 | 2020-01-02 | 2 | 270
    X | 2020-01-02 | 3 | 298
    是 | 2020-01-02 | 3 | 259
    X | 2020-01-02 | 4 | 280
    是 | 2020-01-02 | 4 | 285
    X | 2020-01-03 | 1 | 260
    是 | 2020-01-03 | 1 | 265
    X | 2020-01-03 | 2 | 280
    是 | 2020-01-03 | 2 | 260
    X | 2020-01-03 | 3 | 285
    是 | 2020-01-03 | 3 | 290
    X | 2020-01-03 | 4 | 290
    是 | 2020-01-03 | 4 | 280
    -------------------------------------------------- -------------------------

    预期结果
    -------------------------------------------------- -------------------------
    患者姓名 | 报告日期 | 阅读No | 测量
    -------------------------------------------------- -------------------------
    X | 2020-01-03 | 4 | 290
    是 | 2020-01-03 | 4 | 280
    -------------------------------------------------- -------------------------

我可以做到 C# 如下。任何人都可以帮助用Java翻译它吗?

    使用 System.Collections.Generic;
    使用 System.Linq;

    公开课程序
    {
        公共静态无效 Main()
        {
            Console.WriteLine("--------------------------------- ------------------");
            Console.WriteLine(String.Format("{0} |\t{1}\t| {2} |\t{3}", "PatientName", "ReportDate", "ReadingNo", "Measurement"));
            Console.WriteLine("--------------------------------- ------------------");
            列表 lst = 新列表
            {
                新患者(){Name="X", ReportDate="2020-01-02", ReadingNo=1, Measurement=255 },
                新患者(){Name="Y", ReportDate="2020-01-02", ReadingNo=1, Measurement=250 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=2, Measurement=266 },
                新患者(){Name="Y", ReportDate="2020-01-02", ReadingNo=2, Measurement=270 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=3, Measurement=298 },
                新患者(){Name="Y", ReportDate="2020-01-02", ReadingNo=3, Measurement=259 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=4, Measurement=280 },
                新患者(){Name="Y", ReportDate="2020-01-02", ReadingNo=4, Measurement=285 },
                新患者(){Name="X", ReportDate="2020-01-03", ReadingNo=1, Measurement=260 },
                新患者(){Name="Y", ReportDate="2020-01-03", ReadingNo=1, Measurement=265 },
                新患者(){Name="X", ReportDate="2020-01-03", ReadingNo=2, Measurement=280 },
                新患者(){Name="Y", ReportDate="2020-01-03", ReadingNo=2, Measurement=260 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=3, Measurement=285 },
                新患者(){Name="Y", ReportDate="2020-01-03", ReadingNo=3, Measurement=290 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=4, Measurement=290 },
                新患者(){Name="Y", ReportDate="2020-01-03", ReadingNo=4, Measurement=280 }
            };
            lst.ForEach(p=>{
                Console.WriteLine(p.toString());
            });
            Console.WriteLine("--------------------------------- ------------------");

            var lstLatest = 从 lst 中的 p
                  按 p.Name 分组 p
                      进入g
                      选择 g.OrderByDescending(p => p.ReportDate).ThenByDescending(p=>p.ReadingNo).ToList();
            foreach(lstLatest 中的 var p)
            {
                Console.WriteLine(p.First().toString());
            }


        }
    }

    公开课患者
    {
        公共字符串名称 { 获取;放;}
        公共字符串 ReportDate {get;set;}
        public int ReadingNo {get;set;}
        公共 int 测量 {get;set;}
        公共字符串 toString()
        {
            return String.Format("{0}\t\t\t|\t{1}\t|\t{2} \t|\t{3}", this.Name, this.ReportDate, this.ReadingNo , this. 测量);
        }
    }

标签: javac#

解决方案


谢谢@TemaTre。您的意见有所帮助。工作代码看起来像


    地图地图=
                lst.stream().collect(
                    Collectors.groupingBy(
                        患者::getName,
                        Collectors.collectingAndThen(
                            Collectors.toList(),
                            值-> values.stream()
                                .sorted(Comparator.comparing(Patient::getReportDate, Comparator.nullsFirst(Comparator.naturalOrder()))
                                        .thenComparing(Patient::getReadingNo, Comparator.nullsFirst(Comparator.naturalOrder())).reversed())
                                .collect(toList()).get(0)

                            )));

Java中完整的工作代码如下

import java.util.*;
    import java.util.stream.Collectors;
    import static java.util.stream.Collectors.*;
    public class Main{

         public static void main(String []args){
             List<Patient> lst = new ArrayList<>();
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-02");setReadingNo(1);setMeasurement(255);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-02");setReadingNo(1);setMeasurement(250);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-02");setReadingNo(2);setMeasurement(266);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-02");setReadingNo(2);setMeasurement(270);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-02");setReadingNo(3);setMeasurement(298);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-02");setReadingNo(3);setMeasurement(259);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-02");setReadingNo(4);setMeasurement(280);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-02");setReadingNo(4);setMeasurement(285);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-03");setReadingNo(1);setMeasurement(260);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-03");setReadingNo(1);setMeasurement(265);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-03");setReadingNo(2);setMeasurement(280);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-03");setReadingNo(2);setMeasurement(260);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-03");setReadingNo(3);setMeasurement(285);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-03");setReadingNo(3);setMeasurement(290);}});
             lst.add(new Patient(){{setName("X");setReportDate("2020-01-03");setReadingNo(4);setMeasurement(290);}});
             lst.add(new Patient(){{setName("Y");setReportDate("2020-01-03");setReadingNo(4);setMeasurement(280);}});

             for(Patient p: lst){
                 System.out.println(p.toString());
             }
             System.out.println("---------------------------");

             Map<String, Patient> map = 
                lst.stream().collect(
                    Collectors.groupingBy(
                        Patient::getName,
                        Collectors.collectingAndThen(
                            Collectors.toList(), 
                            values -> values.stream()
                                .sorted(Comparator.comparing(Patient::getReportDate, Comparator.nullsFirst(Comparator.naturalOrder()))
                                        .thenComparing(Patient::getReadingNo, Comparator.nullsFirst(Comparator.naturalOrder())).reversed())
                                .collect(toList()).get(0)

                            )));

            for (Map.Entry<String,Patient> entry : map.entrySet()) {
                System.out.println(entry.getValue().toString());
            } 


         }
    }

     class Patient{
        private String Name;
        public String getName(){
            return Name;
        }
        public void setName(String name){
            this.Name=name;
        }

        private String ReportDate;
        public String getReportDate(){
            return ReportDate;
        }
        public void setReportDate(String reportDate){
            this.ReportDate=reportDate;
        }

        private int ReadingNo;
        public int getReadingNo(){
            return ReadingNo;
        }
        public void setReadingNo(int readingNo){
            this.ReadingNo=readingNo;
        }

        private int Measurement;
        public int getMeasurement(){
            return Measurement;
        }
        public void setMeasurement(int measurement){
            this.Measurement=measurement;
        }

        public String toString(){
            return String.format("%s\t%s\t%d\t%d", Name, ReportDate, ReadingNo, Measurement);
        }
    }

推荐阅读