对List数据进行汇总,要求count相同,且日期必须连续,对日期进行合并
----------原始数据------------- date count 2019-01-01 1 2019-01-02 1 2019-01-03 1 2019-01-05 2 2019-01-07 3
-----------转变为---------------- startdate enddate count 2019-01-01 2019-01-03 1 2019-01-05 2019-01-05 2 2019-01-07 2019-01-07 3
方式1
package com.zhaopin.recruiteffect.activity; import java.util.*; import org.apache.commons.lang3.RandomUtils; import org.assertj.core.util.Lists; import org.junit.Test; public class ReduceTest{ class Target { Long start; Long end; int num; public Long getStart() { return start; } public void setStart(Long start) { this.start = start; } public Long getEnd() { return end; } public void setEnd(Long end) { this.end = end; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public String toString() { return "[start:"+ new Date(this.start).toLocaleString()+ ",end:"+ new Date(this.end).toLocaleString()+ ",num:"+this.num+"]"; } } @Test public void test() throws InterruptedException { long date = 1546272000000L; List<Target> list = Lists.newArrayList(); for (int i = 1; i <= RandomUtils.nextInt(10, 30); i++) { Target s = new Target(); s.setStart(date); s.setEnd(date); s.setNum(RandomUtils.nextInt(1, 3)); list.add(s); if (RandomUtils.nextBoolean()) { date = date + 86400000 + 86400000; } else { date = date + 86400000; } } System.err.println("List: " + list); List<Target> targetList=new ArrayList<>(); Optional<Target> result1 = list.stream().reduce((acc, item) -> { Target t=new Target(); t.setStart(acc.getStart()); t.setNum(acc.getNum()); // 日期不连续、数量不一致 if (acc.num != item.num || acc.getEnd() + 86400000 != item.getStart()) { t.setEnd(acc.getEnd()); acc=item; targetList.add(t); } else { acc.setEnd(item.getStart()); } return acc; }); if (result1.isPresent()) { targetList.add(result1.get()); } System.err.println("targetList:"+targetList); } }方式二
import java.util.ArrayDeque; import java.util.Comparator; import java.util.List; import java.util.function.Consumer; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.apache.commons.lang3.RandomUtils; import org.assertj.core.util.Lists; import org.junit.Test; public class ContinueTest { @Setter @Getter @ToString class Sale { Long date; int num; } @Setter @Getter @ToString class Target { Long start; Long end; int num; } @Test public void test1() throws InterruptedException { long date = 1546272000000L; List<Sale> list = Lists.newArrayList(); for (int i = 1; i <= RandomUtils.nextInt(10, 30); i++) { Sale s = new Sale(); s.setDate(date); s.setNum(RandomUtils.nextInt(1, 3)); list.add(s); date = date + 86400000; } List<Target> result = Lists.newArrayList(); // 中转队列 ArrayDeque<Sale> queue = new ArrayDeque<>(); Consumer<Sale> func = (f) -> { if (f == null && queue.size() == 0) { return; } Target t = new Target(); Sale e = queue.poll(); t.setStart(e.getDate()); t.setNum(e.getNum()); for (e = queue.poll(); e != null; e = queue.poll()) { t.setEnd(e.getDate()); } if (t.getEnd() == null) { t.setEnd(t.getStart()); } System.err.println("t: " + t); result.add(t); if (f != null) { queue.addFirst(f); } }; list.stream().sorted(Comparator.comparing(Sale::getDate)).forEach(s -> { // 时间连续、且数量一致,则分到一个Target if (queue.isEmpty()) { queue.add(s); } else { Sale last = queue.getLast(); if (last.getNum() != s.getNum() || last.getDate() + 86400000 != s.getDate()) { // 日期不连续、数量不一致 func.accept(s); } else { queue.add(s); } } }); func.accept(null); System.err.println("List: " + list); System.err.println("Target: " + result); } }