不使用Map或Sets成对排序列表

时间:2016-06-02 06:39:26

标签: java hashmap

我有一个奇怪的问题,我在三列学生中有数据如下,

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

我的目标是找到每个学生的最低InitDAte和同一学生的最高FinDate。 所有数据都存储为字符串,因此我必须使用DateFormat来解析我使用的日期,以便先解析日期。

最初,我尝试将数据存储为StudentInitDAte和其他对StudentFinDate,然后我尝试将数据存储在{{ 1}}以日期作为键,但问题是它只存储唯一数据,如果两个学生的初始日期相同,那么其中只有一个将存储在散列图中。

我意识到我无法使用HashMapSet存储数据,因为它只会存储唯一值,所以我决定使用Maps

我创建了3个列表,一个是List类型,另外两个是类型String,所以我可以存储重复数据。 我已将所有学生姓名存储在一个列表中,并将日期存储在其他两个列表中。

我现在要做的是按照学生的方式对学生列表进行排序,DateInitDAte也将根据学生进行排序。

无论如何根据其他列表对一个列表进行排序,就像我们在哈希映射的情况下一样?

5 个答案:

答案 0 :(得分:1)

您是否考虑过使用您需要的属性编写自己的学生课程,然后将其存储为学生对象列表? 然后,您可以遍历学生对象列表以查找初始日期的最低值,然后再次迭代以找到最高的结束日期,其中学生ID等于您找到的第一个学生对象的学生ID。

答案 1 :(得分:1)

您需要将所有学生存储在一个列表中,然后根据最小初始日期和最大结果日期编写您自己的自定义比较器进行排序,以下是解决方案。

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

}

这将给出以下输出:

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 :(得分:0)

另一种可能的解决方案是拥有2个Maps,InitDates和FinDates,其中学生ID是键,值是可以订购的日期列表。

答案 3 :(得分:0)

为什么使用所有您感兴趣的日期列表是最小/最大?只需为每个学生保留minInitDate / maxFinDate,当您扫描一行时,将该行中的日期与该对中的日期进行比较,并在必要时进行替换。

答案 4 :(得分:0)

事实上,您无需对列表进行排序。由于排序算法的最小顺序是O(n * log(n))。我认为以下解决方案更好,因为它的顺序是O(n)。它使用HashMap来保存每个学生的最小initDate和最大finDate。

主要课程:

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

    }
}

学生班:

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类:

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