利用期間重複の詳細リストを求める(1)
利用期間重複の詳細リストを求める(2)
これらの最終目的である重複の状況を求めるもの。サンプルを作ってみた。。
List<Element> list = createElementList();
// 日付単位の重複状況
final Map<Date, TreeSet<Element>> resultDailyMap = new HashMap<Date, TreeSet<Element>>();
// 重複期間 Map
final Map<String, TreeSet<Element>> resultPeriodMap = new HashMap<String, TreeSet<Element>>();
List<Element> results = list.stream().collect(ArrayList::new, (List<Element> rlist, Element t)->{
list.stream().filter*1;
set.add(e);
set.add(t);
resultDailyMap.put(d, set);
String periodKey = simpledateformatSlash.format(start) + "_" + simpledateformatSlash.format(end);
set = resultPeriodMap.containsKey(periodKey) ? resultPeriodMap.get(periodKey) : new TreeSet<Element>*2;
set.add(e);
set.add(t);
resultPeriodMap.put(periodKey, set);
});
rlist.add(e);
}
});
}, (t, u)->{}
).stream().distinct().collect(Collectors.toList());
//
System.out.println("============ 重複発生した Element ==============");
results.stream().forEach*3.toLocalDate(), e.end_date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
System.out.println(e + " --> " + (p.getDays() + 1));
});
System.out.println("");
System.out.println("============ 重複期間 Map 状況 ===============");
resultPeriodMap.keySet().stream().sorted().forEach(p->{
StringBuilder sb = new StringBuilder();
sb.append(p);
String[] ary = p.split("_");
int days = Period.between(LocalDate.parse(ary[0], dateformatSlash), LocalDate.parse(ary[1], dateformatSlash)).getDays() + 1;
sb.append(" " + Integer.toString(days) + " ");
sb.append( resultPeriodMap.get(p).stream().map(t->{return t.toString();}).collect(Collectors.joining(", ", "[", "]")) );
System.out.println(sb.toString());
});
System.out.println("");
System.out.println("============ 日付単位の重複状況 ===============");
resultDailyMap.keySet().stream().sorted().forEach(d->{
StringBuilder sb = new StringBuilder();
sb.append( dateformat.format(d) );
sb.append( "--->" );
sb.append( resultDailyMap.get(d).stream().map(t->{return t.toString();}).collect(Collectors.joining(", ", "[", "]")) );
System.out.println(sb.toString());
});
======
public Stream<Date> createDateStream(Date start, Date end){
LocalDateTime ldt = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
Period p = Period.between(start.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), end.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
return IntStream.range(0, p.getDays() + 1).mapToObj(i->ldt.plusDays(i)).map(d->Date.from(d.atZone(ZoneId.systemDefault()).toInstant()));
}
============================
やっぱり、 LocalDate を使おう!
*1:e)->{ return !e.equals(t);}).forEach((e)->{
if (t.start_date.compareTo(e.end_date) <= 0 && t.end_date.compareTo(e.start_date) >= 0){
Date start = e.start_date.compareTo(t.start_date) <= 0 ? t.start_date : e.start_date;
Date end = e.end_date.compareTo(t.end_date) <= 0 ? e.end_date : t.end_date;
// 2つの日付から Streamを生成=createDateStream
createDateStream(start, end).forEach(d->{
TreeSet<Element> set = resultDailyMap.containsKey(d) ? resultDailyMap.get(d) : new TreeSet<Element>((a, b)->a.start_date.compareTo(b.start_date
*2:a, b)->a.start_date.compareTo(b.start_date
*3:e)->{
Period p = Period.between(e.start_date.toInstant().atZone(ZoneId.systemDefault(