嵌套集合中的操作

时间:2016-09-23 10:51:51

标签: java collections enums

我正在尝试创建自己的个人假期跟踪系统,在这个系统中,我将能够计算出一个人缺少的天数,以及出于什么原因。

我想用于此的数据结构是Map<String, List<Map<LeaveType, Integer>>>

的数据结构

我创建的LeaveType enum看起来像这样:

枚举

public enum LeaveType {
    casual(5), sick(5), earned(10);

    private int leave_days;

    private LeaveType(int days){
        this.leave_days = days;
    }

    public int getNoOfDays(){
        return this.leave_days;
    }
}

如您所见,系统将使用三种类型的树叶,即休闲,生病和挣钱。

我从我在MySQL中创建的本地表中提取数据。这是架构描述:

表架构

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| first_name  | varchar(50) | YES  |     | NULL    |       |
| second_name | varchar(50) | YES  |     | NULL    |       |
| from_date   | date        | YES  |     | NULL    |       |
| to_date     | date        | YES  |     | NULL    |       |
| reason      | varchar(15) | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

如您所见,我将提取姓名,姓名,休假日期,休假日期以及休假类型。

我用来提取它的结构如下:

EmpBean.java

import java.util.Comparator;
import java.util.Date;

public class Empbean{
    private String first_name;
    private String last_name;
    private Date fromDate;
    private Date toDate;
    private LeaveType reason;


    public Empbean(String fname, String lname, Date from, Date to, LeaveType reason){
        this.first_name = fname;
        this.last_name = lname;
        this.fromDate = from;
        this.toDate = to;
        this.reason = reason;
   }

    public String getFirst_name() {
        return first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public Date getFromDate() {
        return fromDate;
    }

    public Date getToDate() {
        return toDate;
    }

    public LeaveType getReason() {
        return reason;
    }

    @Override
    public int hashCode() {
        //use the classic 31-17 hashcode override
        int result = 17;
        result = 31 * result + first_name.hashCode();
        result = 31 * result + last_name.hashCode();
        result = 31 * result + fromDate.hashCode();
        result = 31 * result + toDate.hashCode();
        result = 31 * result + reason.hashCode();

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj!= null && obj instanceof Empbean){
            Empbean other = (Empbean) obj;
            //this and other
            if((this.getFirst_name().equals(other.getFirst_name())&&
                (this.getLast_name().equals(other.getLast_name())))){
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return new String("First Name: "+this.getFirst_name()+", Last Name: "+this.getLast_name()+ "Leave from: "+this.getFromDate()+", Leave to: "+this.getToDate()+"+ "Reason: "+this.getReason());
    }
}

成功填充数据后,我有一个方法,它接受一个String作为参数,以及EmpBeans列表。这种方法应该:

  • 计算编号。日期之间的天数
  • 将该值映射到枚举
  • 创建所有此类地图的列表
  • 将此列表映射到搜索名称
  • 返回地图

我的目标返回类型是Map<String, List<LeaveType, Integer>>

以下是我用来执行此操作的方法:

@Override
public Map<String, List<Map<LeaveType, Integer>>> getAllLeaveRecords(
        List<Empbean> map, String name) throws NameNotFoundException{

        //sentinal
        boolean hit = false;

        //start from inner
        Map<LeaveType, Integer> innerMostData = null;
        List<Map<LeaveType, Integer>> secondLastData = null;
        Map<String, List<Map<LeaveType, Integer>>> outermostData = null;

        //first, iterate over the entire employee array, and find the ones which match the input
        for(int i = 0;i<map.size();i++){
            //if present
            if(map.get(i).getFirst_name().equalsIgnoreCase(name) || map.get(i).getLast_name().equalsIgnoreCase(name)){
                hit = true;

                //extract required data
                leave = map.get(i).getReason(); //THIS --- (1)

                /*
                 * calculation of no. of days
                 * 
                 * */

                java.util.Date from = map.get(i).getFromDate();
                java.util.Date to = map.get(i).getToDate();
                long difference = to.getTime() - from.getTime();
                int no_of_days_in_between = (int)difference/(24*60*60*1000);    //AND THIS --- (2)

                if(innerMostData == null){
                    innerMostData = new HashMap<LeaveType, Integer>();
                }

                Integer current = innerMostData.get(leave);
                if(current == null){
                    current = 0;
                }

                innerMostData.put(leave, current + no_of_days_in_between);

                if(secondLastData == null){
                    secondLastData = new ArrayList<Map<LeaveType,Integer>>();
                }

                secondLastData.add(innerMostData);

                if(outermostData == null){
                    outermostData = new HashMap<String, List<Map<LeaveType,Integer>>>();
                }
                outermostData.put(name, secondLastData);
            }
        }

        if(hit == false){   //if not found throughout
            throw new NameNotFoundException();
        }

        return outermostData;
}

我瞄准的输出是这样的:

{SomeName=[{LeaveType1, total_days_of_leave}, {leaveType2, total_days_of_leave}, ...]}

在具有搜索名称&#39; rahul&#39;的数据集上运行该方法后,我得到以下输出:

{rahul=[{sick=-7, earned=6}, {sick=-7, earned=6}, {sick=-7, earned=6}, {sick=-7, earned=6}, {sick=-7, earned=6}]}

有人可以告诉我哪里出错了吗?

1 个答案:

答案 0 :(得分:0)

在循环的每次迭代中,您add()在列表secondLastData末尾添加一个新元素。由于您只创建了一个innerMostData,因此它始终是对同一对象的引用。基本上,secondLastData可以省略;您应该将innerMostData直接添加到outerMostData