简体   繁体   中英

Sorting List in pairs without using Map or Sets

I have a strange problem in which I have data in three columns of students as follows,

Student    InitDAte      FinDate
    ABC   2/2/2016     5/5/2017
    ABC   3/2/2016     3/30/2017
    CED   1/1/2015     3/12/2017
    LEF   1/12/2016    11/17/2017
    CED   1/12/1999    12/23/207
    LEF   2/13/2000    11/19/2017

My goal is to find the lowest InitDAte of every student and highest FinDate of the same student. All the data is stored as a string so I have to parse the dates which I have done using DateFormat to parse the date first.

Initially, I tried storing data in a pair as Student , InitDAte and other pair Student , FinDate , and then I tried storing the data in a HashMap with date as a key but the problem is it will only store unique data and if two students have same initial dates then only one of them will be stored in the hashmap.

I realized i cannot use Set and Maps to store data as it will only store unique values so I have decided to use List .

I have created 3 lists, one of type String and the other two of type Date , so I can store duplicate data. I have stored all the Student names in one list and dates in other two lists.

What I want to do now is sort the List of students in such a way that InitDAte and FinDate will also be sorted according to the student.

Is there anyway to sort one list based on the other list like we do in case of hashmaps ?

Have you considered writing your own student class with the properties that you need and then storing them as a list of student objects? You can then iterate through the list of student objects to find the lowest value of init date and then iterate through once more to find the highest fin date where the student id is equal to the student id of your first student object you've found.

you need to store all students in a list and then write your own custom Comparator to sort based on min init Date and max fin Date, Below is the solution .

public class SortStudent {
    public static void main(String args[]){
        List<Student> stuList= new ArrayList<Student>();
        stuList.add(new Student("ABC",new Date("2/2/2016"),new Date("5/5/2017")));
        stuList.add(new Student("ABC",new Date("3/2/2016"),new Date("3/30/2017")));
        stuList.add(new Student("CED",new Date("1/1/2015"),new Date("3/12/2017")));
        stuList.add(new Student("CED",new Date("1/12/1999"),new Date("12/23/2017")));
        stuList.add(new Student("LEF",new Date("1/1/2016"),new Date("11/17/2017")));
        stuList.add(new Student("LEF",new Date("2/13/2000"),new Date("11/19/2017")));

        Set<Student> stuSet = new HashSet<Student>(stuList);
        List<Student> stuListTemp= new ArrayList<Student>();



        for(Student stu : stuSet){
            for(Student student : stuList){
                if(student.equals(stu)){
                    stuListTemp.add(student);
                }
            }

            Collections.sort(stuListTemp, new findMinInitDate());
            System.out.println("Student Name : " + stu.getName());
            System.out.println("Min initDate : " + stuListTemp.get(0).getInitDate());
            Collections.sort(stuListTemp, new findMaxFinDate());
            System.out.println("Max FinDate : " + stuListTemp.get(0).getFinDate());
            stuListTemp.clear();
        }
    }
}

class Student {

    private String name;
    private Date initDate;
    private Date finDate;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getInitDate() {
        return initDate;
    }
    public void setInitDate(Date initDate) {
        this.initDate = initDate;
    }
    public Date getFinDate() {
        return finDate;
    }
    public void setFinDate(Date finDate) {
        this.finDate = finDate;
    }

    public Student(String name, Date initDate, Date finDate) {
        super();
        this.name = name;
        this.initDate = initDate;
        this.finDate = finDate;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", initDate=" + initDate
                + ", finDate=" + finDate + "]";
    }


}

class findMinInitDate implements Comparator<Student>{

    @Override
    public int compare(Student stu1, Student stu2) {
        return (stu1.getInitDate().before(stu2.getInitDate()))?-1:1;
    }

}

class findMaxFinDate implements Comparator<Student>{

    @Override
    public int compare(Student stu1, Student stu2) {
        return (stu1.getFinDate().before(stu2.getFinDate()))?1:-1;
    }

}

This will give below output :

Student Name : ABC
Min initDate : Tue Feb 02 00:00:00 IST 2016
Max FinDate : Fri May 05 00:00:00 IST 2017
Student Name : LEF
Min initDate : Sun Feb 13 00:00:00 IST 2000
Max FinDate : Sun Nov 19 00:00:00 IST 2017
Student Name : CED
Min initDate : Tue Jan 12 00:00:00 IST 1999
Max FinDate : Sat Dec 23 00:00:00 IST 2017

另一个可能的解决方案是使用2个Maps,InitDates和FinDate,其中学生ID是键,值是日期列表,可以排序。

Why use lists of dates when all you are interested in is min/max? Just keep minInitDate/maxFinDate for every student, and when you scan a line compare the dates from the line to the dates in this pair, and replace if necessary.

In fact you don't need to sort your list. Since minimum order of sorting algorithms is O(n*log(n)). I think the following solution is better, because its order is O(n). It uses a HashMap to hold minimum initDate and maximum finDate for each Student.

Main class:

package com.stackoverflow;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class Main {
    public Main() {
        super();
    }

    public static void main(String[] args) throws ParseException {
        List<Student> list = new ArrayList<Student>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy");

        Student student =
            new Student("ABC", dateFormat.parse("2/2/2016"), dateFormat.parse("5/5/2017"));
        list.add(student);

        student =
                new Student("ABC", dateFormat.parse("3/2/2016"), dateFormat.parse("3/30/2017"));
        list.add(student);

        student =
                new Student("CED", dateFormat.parse("1/1/2015"), dateFormat.parse("3/12/2017"));
        list.add(student);

        student =
                new Student("LEF", dateFormat.parse("1/12/2016"), dateFormat.parse("11/17/2017"));
        list.add(student);

        student =
                new Student("CED", dateFormat.parse("1/12/1999"), dateFormat.parse("12/23/2017"));
        list.add(student);

        student =
                new Student("LEF", dateFormat.parse("2/13/2000"), dateFormat.parse("11/19/2017"));
        list.add(student);

        Map<String, DatePair> map =
            new HashMap<String, DatePair>(list.size() / 2);
        for (Student st : list) {
            DatePair datePair = map.get(st.getName());
            if (datePair == null) {
                datePair = new DatePair(st.getInitDate(), st.getFinDate());
                map.put(st.getName(), datePair);
            } else {
                if (st.getInitDate().before(datePair.getInitDate()))
                    datePair.setInitDate(st.getInitDate());
                if (st.getFinDate().after(datePair.getFinDate()))
                    datePair.setFinDate(st.getFinDate());
            }
        }

        for (Map.Entry<String, DatePair> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

    }
}

Student Class:

package com.stackoverflow;

import java.util.Date;

public class Student {
    private String name;
    private Date initDate;
    private Date finDate;

    public Student() {
        super();
    }

    public Student(String name, Date initDate, Date finDate) {
        super();
        this.name = name;
        this.initDate = initDate;
        this.finDate = finDate;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setInitDate(Date initDate) {
        this.initDate = initDate;
    }

    public Date getInitDate() {
        return initDate;
    }

    public void setFinDate(Date finDate) {
        this.finDate = finDate;
    }

    public Date getFinDate() {
        return finDate;
    }
}

DatePair Class:

package com.stackoverflow;

import java.text.SimpleDateFormat;

import java.util.Date;

public class DatePair {
    private Date initDate;
    private Date finDate;

    public DatePair() {
        super();
    }

    public DatePair(Date initDate, Date finDate) {
        super();
        this.initDate = initDate;
        this.finDate = finDate;
    }

    public void setInitDate(Date initDate) {
        this.initDate = initDate;
    }

    public Date getInitDate() {
        return initDate;
    }

    public void setFinDate(Date finDate) {
        this.finDate = finDate;
    }

    public Date getFinDate() {
        return finDate;
    }

    @Override
    public String toString() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy");
        return "(" + dateFormat.format(initDate) + ", " + dateFormat.format(finDate) + ")";
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM