Вы можете сопоставить даты с суммой ставок. Затем отфильтруйте их.
public List<String> findLimits(List<Bet> bets) {
return bets.stream()
.collect(Collectors.toMap(
b -> b.getCustId() + LocalDate.ofInstant(b.getTimestamp(), ZoneOffset.UTC).toString(),
Bet::getAmount,
(o1, o2) -> o1 + o2))
.entrySet().stream()
.filter(e -> e.getValue() > 100.0)
.map(e -> e.getKey().substring(0, e.getKey().length() - LocalDate.EPOCH.toString().length()))
.collect(Collectors.toList());
}
You would need to write the condition out everytime you use size()
. It's convenient to use empty()
. This is of course, provided you don't switch containers. As others have pointed out, it is upto the implementation to use size()
in empty()
or not. However, the standard does guarantee that: empty()
is a constant-time operation for all
стандартные контейнеры.
empty () имеет O (1) реализаций для ВСЕХ контейнерных классов. size () может предоставить только O (n) реализаций для некоторых контейнеров; Вот почему empty () является предпочтительным.
Потому что, если вы переключитесь с std :: vector на std :: list или другой контейнер, оно может быть другим.
Например, некоторые реализации std :: list :: size
принимают O (n)
, а не O (1)
.
Ну, как вы говорите, это просто деталь реализации. std :: list
может быть реализован либо с сохраненным размером (постоянное время size ()
, но с линейным временем splice ()
), либо без (константа -time splice ()
, но с линейным временем size ()
). Выбирая empty ()
, вы избегаете ставок на детали реализации, когда вам не нужно знать размер.
Следуя стандарту, рекомендуется использовать empty (), поскольку он имеет постоянную сложность по времени независимо от типа контейнера.
В стандарте C ++ 03, глава 23.1, таблица 65: Требования к контейнерам
Operation: empty()
Return_type: convertible to bool
Semantics: equivalent to size()==0
Complexity: constant
Похоже, что в вашей реализации STL они приняли семантику как реальную реализацию, игнорируя требования сложности, или size () - постоянное время в реализация (сохраненное поле).
Если size () не является постоянным временем, обратитесь к поставщику по поводу того, что std :: list <> :: empty () не удовлетворяет стандартным требованиям контейнера.
1-й, используя функция с именем empty ()
, когда вы хотите узнать, пусто ли что-то, делает код более читабельным и означает, что вам не нужно беспокоиться о деталях реализации. Это также означает, что ваш код легче адаптировать к другим типам контейнеров с другими характеристиками.
Во-вторых, это всего лишь одна реализация STL. Мой GNU C ++ выглядит так:
bool
empty() const
{ return begin() == end(); }
Это в конечном итоге приведет к сравнению указателей, а использование size () приведет к вычитанию (в этой реализации).
В-третьих, маловероятно, что это приведет к накладным расходам. дополнительный вызов функции, поскольку функция empty ()
, вероятно, является встроенной (в обеих реализациях).
В дополнение к причинам, приведенным выше, это также возможно более ясно, чем foo.size () == 0 и / или ! foo.size ()
Кроме точки читабельности, что очень правильно, вы испытали просто артефакты одной конкретной реализации, а не только один возможный.
То есть, нет причины или требования, чтобы empty () был реализован в терминах size () как в случае вектора, так и в списке, или в любом другом контейнере. Если есть более эффективные альтернативы, их следует использовать, если автор (ы) библиотеки некомпетентны или, что более разумно, ленивы.
Что касается списка и O (1) -размера size (), или его отсутствие, вы должны принять во внимание, что list может реализовывать либо size () как O (1), либо splice (), но не оба (думать о причине - интересное упражнение). Так что в вашем случае,