我有一个Java 8 LocalDateTime
(时间戳)的列表/流,它按升序(时间顺序)。
2019-03-01T13:13:13
2019-03-01T15:15:15
2019-03-02T12:12:12
2019-03-02T14:14:14
2019-03-03T11:11:11
2019-03-03T08:08:08
如何快速找到给定12小时内的子列表,而不循环查看列表的所有元素。我知道只是做一个过滤器会很简单,但是会循环整个列表(假设列表很大)
如果开始时间戳为2019-03-01T10:10:10
,则结束时间戳为2019-03-01T22:22:21
时间戳子列表必须在开始之后和结束之前。
答案 0 :(得分:0)
您可以尝试查看列表的两端,对索引进行计数,直到找到等于或小于所需开始时间的第一个索引,然后向后迭代以获取所需时间段中最后一次的索引。 像这样:
int first;
for (LocalDateTime time : timeStampList){
if (time.compareTo(startTime) < 0){
first++;
}else{
return i + 1;
}
}
int last = list.length();
while (last > 0){
LocalDateTime time = timeStampList[last];
if (time.compareTo(endTime) > 0){
last -= 1;
}else{
return last - 1;
}
}
您要查找的子集将是这些索引之间(包括两端)的所有内容
答案 1 :(得分:0)
您可以使用NavigableSet
的{{3}}方法
NavigableSet subSet(E fromElement, 来自Inclusive的布尔值, E toElement, boolean toInclusive)
可能是这样的:
NavigableSet<LocalDateTime> treeSet = new TreeSet<>(yourListWithTimestamps);
//Initialize your start and end date-times:
LocalDateTime start = LocalDateTime.parse("2019-03-01T10:10:10");
LocalDateTime end = LocalDateTime.parse("2019-03-01T22:22:21");
NavigableSet<LocalDateTime> subSet = treeSet.subSet(start, false, end, false);
//Optional - convert it back to list:
List<LocalDateTime> subList = new ArrayList<>(subSet);
答案 2 :(得分:0)
我可以为您建议以下根本不使用drop的代码:
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SublistWithLambda {
public static void main(String[] args) {
List<LocalDateTime> dates = Arrays.asList(
LocalDateTime.now().minusHours(24),
LocalDateTime.now().minusHours(22),
LocalDateTime.now().minusHours(20),
LocalDateTime.now().minusHours(12),
LocalDateTime.now().minusHours(10),
LocalDateTime.now().minusHours(7),
LocalDateTime.now().minusHours(5)
);
BiPredicate<LocalDateTime, LocalDateTime> isLessThan12Hours = (date1, date2) -> {
Duration duration = Duration.between(date2, date1);
return duration.toHours() >= 0 && duration.toHours() <= 12;
};
List<List<LocalDateTime>> result = IntStream
.range(0, dates.size())
.mapToObj(i -> dates.stream().skip(i)
.takeWhile(date -> isLessThan12Hours.test(date, dates.get(i)))
.collect(Collectors.toList()))
.collect(Collectors.toList());
result.forEach(System.out::println);
}
}
我希望这就是您想要的。