Java 8 Stream of LocalDateTime, как найти их список без зацикливания всего - PullRequest
0 голосов
/ 10 марта 2019

У меня есть список / поток 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

Подсписок метки времени должен быть после начала и до конца.

Ответы [ 3 ]

0 голосов
/ 10 марта 2019

Вы можете использовать subSet метод NavigableSet

NavigableSet subSet (E fromElement, логический fromInclusive, E toElement, логический 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);
0 голосов
/ 10 марта 2019

Я могу предложить вам следующий код, который вообще не использует 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);
    }
}

Я надеюсь, что это то, что вы ищете.

0 голосов
/ 10 марта 2019

Вы можете попытаться просмотреть оба конца списка, подсчитывая индексы до тех пор, пока не найдете первый индекс после или не равный требуемому времени начала, и итерируя в обратном направлении, чтобы получить индекс последнего времени за период, который вы ищете,Что-то вроде:

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;
    }
}

Подмножество, которое вы будете искать, будет между этими индексами (включительно)

...