読者です 読者をやめる 読者になる 読者になる

利用期間重複の詳細リストを求める(3)

java.util.Date を使ってることに抵抗を感じながら、とりあえず
利用期間重複の詳細リストを求める(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(