在 Java 代码中创建和初始化 `HashMap<Date, Date>` 的最佳方法?

问题描述 投票:0回答:6

它将包含以下条目:

{{Date(2014, 1, 1), Date(2013, 11, 31)},
 {Date(2014, 1, 11), Date(2013, 11, 31)},
 {Date(2014, 1, 21), Date(2013, 11, 31)},
 {Date(2014, 1, 31), Date(2013, 11, 31)}}

我目前正在使用这个:

public static Map<Date, Date> dateMap = new HashMap<Date, Date>(){{
    final Calendar cal = Calendar.getInstance();
    final Calendar cal2 = Calendar.getInstance();
    cal.set(2014, 0, 1, 0, 0, 0);
    cal2.set(2013, 11, 31, 0, 0, 0);
    put(cal.getTime(), cal2.getTime());
    cal.set(2014, 0, 11, 0, 0, 0);
    put(cal.getTime(), cal2.getTime());
    cal.set(2014, 0, 21, 0, 0, 0);
    put(cal.getTime(), cal2.getTime());
    cal.set(2014, 0, 31, 0, 0, 0);
    put(cal.getTime(), cal2.getTime());
}};
java date dictionary hashmap
6个回答
2
投票

首先,您使用的 deprecated Date 构造函数无法识别具有数值

12
的月份。 12 月表示为
11
,因此日期
Date(2013, 12, 31)
将导致重新计算。

其次,您现在可以使用 Java 8 的

LocalDate
来简化您的场景。

示例:

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Buhake Sindi
 * @since 03 September 2015
 *
 */
public class Test {

    private static LocalDate[][] localDates = {{LocalDate.of(2014, 1, 1), LocalDate.of(2013, 12, 31)},
                                                {LocalDate.of(2014, 1, 11), LocalDate.of(2013, 12, 31)},
                                                 {LocalDate.of(2014, 1, 21), LocalDate.of(2013, 12, 31)},
                                                 {LocalDate.of(2014, 1, 31), LocalDate.of(2013, 12, 31)}};
    private static Map<Date, Date> dates = new HashMap<>();

    static {
        for (LocalDate[] _localDates : localDates) {
            dates.put(Date.from(_localDates[0].atStartOfDay(ZoneId.systemDefault()).toInstant()), Date.from(_localDates[1].atStartOfDay(ZoneId.systemDefault()).toInstant()));
        }
    }

    public static void main(String[] args) {
        System.out.println(dates);
    }
}

请注意,

LocalDate
中的月份从
1
(一月)到
12
(十二月),而不是像
Date
那样从
0
(一月)和
11
(十二月)开始。


1
投票

这样的事情可能会成功:

int[] dateValues = { 2014, 1,  1, 2013, 12, 31,
                     2014, 1, 11, 2013, 12, 31,
                     2014, 1, 21, 2013, 12, 31,
                     2014, 1, 31, 2013, 12, 31 };
Map<Date, Date> map = new HashMap<>();
Calendar cal = Calendar.getInstance();
cal.clear();
for (int i = 0; i < dateValues.length; i += 6) {
    cal.set(dateValues[i], dateValues[i + 1] - 1, dateValues[i + 2]);
    Date key = cal.getTime();
    cal.set(dateValues[i + 3], dateValues[i + 4] - 1, dateValues[i + 5]);
    map.put(key, cal.getTime());
}

0
投票
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/mm/dd");

String [][] input = {{ "2014/01/01", /* ----> */ "2013/12/31" },
                     { "2014/01/11", /* ----> */ "2013/12/31" },
                     { "2014/01/21", /* ----> */ "2013/12/31" },
                     { "2014/01/31", /* ----> */ "2013/12/31" }};

Map<Date,Date> map = new HashMap<>();

for (String [] in : input)
{
    map.put(sdf.parse(in[0]), sdf.parse(in[1]));
}

0
投票

有很多方法可以做到这一点,这个方法从字符串中解析日期,这使得它们更具可读性:

static final Map<Date, Date> dm;

static {
    try {
        dm = new HashMap<Date, Date>() {
            private static final long serialVersionUID = 1L;
            private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        {
            put(sdf.parse("2014-1-1"), sdf.parse("2013-12-31"));
            put(sdf.parse("2014-1-11"), sdf.parse("2013-12-31"));
            put(sdf.parse("2014-1-21"), sdf.parse("2013-12-31"));
            put(sdf.parse("2014-1-31"), sdf.parse("2013-12-31"));
        }};
    } catch (ParseException e) {
        throw new RuntimeException(e);
    }
}


@Test
public void datemap() {
    System.out.println(dm);
}

0
投票

初始化地图的现代方式

基于OPs解决方案和Buhake Sindi的答案(需要Java 1.8)

private static Date toGlobal(final LocalDate local) {
    return Date.from(local.atStartOfDay(ZoneId.systemDefault()).toInstant());
}

public static final Map<Date, Date> DATES;
static {
    DATES = new HashMap<Date, Date>() {{
            final Date value = toGlobal(LocalDate.of(2013, 12, 31));

            put(toGlobal(LocalDate.of(2014, 1, 1)), value);
            put(toGlobal(LocalDate.of(2014, 1, 11)), value);
            put(toGlobal(LocalDate.of(2014, 1, 21)), value);
            put(toGlobal(LocalDate.of(2014, 1, 31)), value);
        }
    };
}

这可能是初始化地图的好方法,但可能不适合测试环境,因为它会导致不同的

Date
值,具体取决于执行代码的本地时区。

老方法,提供固定/稳定的值

public static final Map<Date, Date> DATES;
static {
    DATES = new HashMap<Date, Date>() {
    {
            final Calendar cal = Calendar.getInstance();
            cal.set(2013, 11, 31);
            final Date value = cal.getTime();

            cal.set(2014, 0, 1);  put(cal.getTime(), value);
            cal.set(2014, 0, 11); put(cal.getTime(), value);
            cal.set(2014, 0, 21); put(cal.getTime(), value);
            cal.set(2014, 0, 31); put(cal.getTime(), value);
        }
    };
}

这可能更适合单元测试。


0
投票

java.time.LocalDate

正如其他人所提到的,存在严重缺陷的

Calendar
类已被 Java 8 及更高版本中内置的 java.time 类所取代。切勿使用
Date
Calendar
SimpleDateFormat

对于仅日期值,请使用

java.time.LocalDate

与遗留类相比,java.time使用合理的编号。因此,1 月至 12 月的月份编号为 1-12。此外,您可以选择使用

Month
枚举对象来进行明显的阅读。

Map.of

在 Java 9+ 中,使用方便的

Map.of
方法来实例化一个 不可修改的
Map
对象。

Map < LocalDate, LocalDate > map =
        Map.of(
                LocalDate.of( 2014 , Month.JANUARY , 1 ) , LocalDate.of( 2013 , Month.NOVEMBER , 30 ) ,
                LocalDate.of( 2014 , Month.JANUARY , 11 ) , LocalDate.of( 2013 , Month.NOVEMBER , 30 ) ,
                LocalDate.of( 2014 , Month.JANUARY , 21 ) , LocalDate.of( 2013 , Month.NOVEMBER , 30 ) ,
                LocalDate.of( 2014 , Month.JANUARY , 31 ) , LocalDate.of( 2013 , Month.NOVEMBER , 30 )
        );

转储到控制台。

System.out.println( "map.toString() = " + map );

map.toString() = {2014-01-01=2013-11-30, 2014-01-31=2013-11-30, 2014-01-21=2013-11-30, 2014-01-11= 2013-11-30}

map.forEach( ( localDate , localDate2 ) -> System.out.println( localDate + "/" + localDate2 ) );

2014-01-01/2013-11-30

2014-01-31/2013-11-30

2014-01-21/2013-11-30

2014-01-11/2013-11-30

© www.soinside.com 2019 - 2024. All rights reserved.