它将包含以下条目:
{{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());
}};
首先,您使用的 deprecated Date 构造函数无法识别具有数值
12
的月份。 12 月表示为 11
,因此日期 Date(2013, 12, 31)
将导致重新计算。
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
(十二月)开始。
这样的事情可能会成功:
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());
}
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]));
}
有很多方法可以做到这一点,这个方法从字符串中解析日期,这使得它们更具可读性:
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);
}
初始化地图的现代方式
基于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);
}
};
}
这可能更适合单元测试。
java.time.LocalDate
正如其他人所提到的,存在严重缺陷的
Calendar
类已被 Java 8 及更高版本中内置的 java.time 类所取代。切勿使用 Date
、Calendar
、SimpleDateFormat
等
对于仅日期值,请使用
java.time.LocalDate
。
与遗留类相比,java.time使用合理的编号。因此,1 月至 12 月的月份编号为 1-12。此外,您可以选择使用
Month
枚举对象来进行明显的阅读。
Map.of
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