检索Java中每个组的第一项

时间:2020-01-14 02:40:45

标签: java c#

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


    Sample Data
    ---------------------------------------------------------------------------
    PatientName  |    ReportDate    | ReadingNo |    Measurement
    ---------------------------------------------------------------------------
    X            |    2020-01-02    |    1      |    255
    Y            |    2020-01-02    |    1      |    250
    X            |    2020-01-02    |    2      |    266
    Y            |    2020-01-02    |    2      |    270
    X            |    2020-01-02    |    3      |    298
    Y            |    2020-01-02    |    3      |    259
    X            |    2020-01-02    |    4      |    280
    Y            |    2020-01-02    |    4      |    285
    X            |    2020-01-03    |    1      |    260
    Y            |    2020-01-03    |    1      |    265
    X            |    2020-01-03    |    2      |    280
    Y            |    2020-01-03    |    2      |    260
    X            |    2020-01-03    |    3      |    285
    Y            |    2020-01-03    |    3      |    290
    X            |    2020-01-03    |    4      |    290
    Y            |    2020-01-03    |    4      |    280
    ---------------------------------------------------------------------------

    Expected result
    ---------------------------------------------------------------------------
    PatientName  |    ReportDate    | ReadingNo |    Measurement
    ---------------------------------------------------------------------------
    X            |    2020-01-03    |    4      |    290
    Y            |    2020-01-03    |    4      |    280
    ---------------------------------------------------------------------------

我可以按以下方式使用C#进行操作。任何人都可以帮助翻译成Java吗?


    using System.Collections.Generic;
    using System.Linq;

    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("---------------------------------------------------------------------------");
            Console.WriteLine(String.Format("{0}  |\t{1}\t| {2} |\t{3}", "PatientName", "ReportDate", "ReadingNo", "Measurement"));
            Console.WriteLine("---------------------------------------------------------------------------");
            List lst = new List
            {
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=1, Measurement=255 },
                new Patient(){Name="Y", ReportDate="2020-01-02", ReadingNo=1, Measurement=250 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=2, Measurement=266 },
                new Patient(){Name="Y", ReportDate="2020-01-02", ReadingNo=2, Measurement=270 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=3, Measurement=298 },
                new Patient(){Name="Y", ReportDate="2020-01-02", ReadingNo=3, Measurement=259 },
                new Patient(){Name="X", ReportDate="2020-01-02", ReadingNo=4, Measurement=280 },
                new Patient(){Name="Y", ReportDate="2020-01-02", ReadingNo=4, Measurement=285 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=1, Measurement=260 },
                new Patient(){Name="Y", ReportDate="2020-01-03", ReadingNo=1, Measurement=265 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=2, Measurement=280 },
                new Patient(){Name="Y", ReportDate="2020-01-03", ReadingNo=2, Measurement=260 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=3, Measurement=285 },
                new Patient(){Name="Y", ReportDate="2020-01-03", ReadingNo=3, Measurement=290 },
                new Patient(){Name="X", ReportDate="2020-01-03", ReadingNo=4, Measurement=290 },
                new Patient(){Name="Y", ReportDate="2020-01-03", ReadingNo=4, Measurement=280 }
            };
            lst.ForEach(p=>{
                Console.WriteLine(p.toString());
            });
            Console.WriteLine("---------------------------------------------------------------------------");

            var lstLatest = from p in lst
                  group p by p.Name
                      into g
                      select g.OrderByDescending(p => p.ReportDate).ThenByDescending(p=>p.ReadingNo).ToList();
            foreach(var p in lstLatest)
            {
                Console.WriteLine(p.First().toString());
            }


        }
    }

    public class Patient
    {
        public string Name { get; set;}
        public string ReportDate {get;set;}
        public int ReadingNo {get;set;}
        public int Measurement {get;set;}
        public string toString()
        {
            return String.Format("{0}\t\t\t|\t{1}\t|\t{2}  \t|\t{3}", this.Name, this.ReportDate, this.ReadingNo, this.Measurement);
        }
    }

3 个答案:

答案 0 :(得分:2)

感谢@TemaTre。您的输入有所帮助。工作代码看起来像



    Map 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)

                            )));

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);
        }
    }

答案 1 :(得分:1)

在Java中,您应该使用流api。

如果需要分组依据,可以使用以下示例:

Map<String, Patient> map = 
getValute().stream().collect(
    Collectors.groupingBy(
        Patient::getName,
        Collectors.collectingAndThen(
            Collectors.toList(), 
            values -> values.get(0))));

例如,如果要使用FirstOrDefault(仅用于教育):

Animal cheetah = animals.stream()
    .filter((animal) -> animal.getNumber() == cheetahNumber)
    .findFirst()
    .orElse(Animal.DEFAULT);

答案 2 :(得分:0)

import static java.util.Comparator.comparing;
import static java.util.Comparator.reverseOrder;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.groupingBy;



    Map<String, List<Patient>> map = lst.stream()
        .collect(groupingBy(Patient::getName, toList()));

    for (List<Patient> group : map.values()) {

        Patient first = group.stream()
            .sorted(comparing(Patient::getReportDate).thenComparing(Patient::getReadingNo, reverseOrder()))
            .findFirst()
            .orElseThrow();

        System.out.println(first);
    }