Как найти максимальный ключ с некоторыми условиями в HashMap, используя Java 8 / Streams?

#java #performance #java-8 #java-stream

#java #Производительность #java-8 #java-stream

Вопрос:

Предположим, у меня есть следующие данные :

введите описание изображения здесь

Вопрос :

  1. Я хочу найти zscore с наибольшим идентификатором заказа, где пара ‘AB’, тип заказа ‘Buy’ и статус ‘InProgress’.

ПРИМЕЧАНИЕ: я сохранил эти данные в HashMap имя — OrderBook, где ключ — OrderID, а значение — OrderModel (PairName, OrderType, Status, zscore).

Решение 1 :

     int maxOrderId = 0 ;
        getOrderBook().entrySet().stream()
                                .filter(e -> e.getValue().getPairName().equals("AB")
                                        amp;amp; e.getValue().getCompletedStatus().equals("InProgress")
                                        amp;amp; e.getValue().getOrderType().equals("Buy"))
                                .forEach(o -> {
                                    if (maxOrderId < o.getKey()) {
                                        maxOrderId = o.getKey();
                                    }
                                });
        
        double zscore = getOrderBook().get(maxOrderId).getzScore();
       System.out.println("Order ID :"  maxOrderId  ", Zscore :" zscore);
  

вывод : Order ID : 5, Zscore : -2.5

Я могу найти zscore, используя приведенный выше код, но я хочу найти за один раз.

Итак, как я могу найти zscore наибольшего OrderID, используя Java 8 / streams, в одной строке?

Есть ли лучший способ, чем мой код?

Ответ №1:

То, что вы ищете, — это max метод:

 Optional<Entry<Long,Order>> maxIdEntry = getOrderBook()
  .entrySet()
  .stream()
  .filter(/* your filter logic */)
  .max(Comparator.comparing(Entry::getKey));
  

Это дает необязательный результат, поэтому используйте методы isPresent() и get() или ifPresent(Consumer<T> consumer) метод для обработки результата

Ответ №2:

Вы можете использовать max() using Comparator для получения наибольшего OrderID и использовать map of Optional для отображения zScore .

 double zscore = getOrderBook()
          .entrySet()
          .stream()
          .filter(e -> e.getValue().getPairName().equals("AB")
                      amp;amp; e.getValue().getCompletedStatus().equals("InProgress")
                      amp;amp; e.getValue().getOrderType().equals("Buy"))
          .max(Comparator.comparing(Entry::getKey))
          .map(e -> e.getValue().getzScore())
          .orElse(0);
  

Ответ №3:

Уже существующий ответ превосходен. Есть и другие способы:

Как насчет использования TreeMap , которое позволяет сортировать ключи? Пока ключ является ex. a String , вам даже не нужно передавать Comparator .

 // create a copy of HashMap as a TreeMap
NavigableMap<String, Order> navigableMap = new TreeMap<>(getOrderBook());

// remove unwanted entries (inverted condition)
navigableMap.entrySet().removeIf(e ->
     !e.getValue().getPairName().equals("AB") ||
     !e.getValue().getCompletedStatus().equals("InProgress") ||
     !e.getValue().getOrderType().equals("Buy"));

// NavigableMap::lastEntry gets an entry with the highest key (by the comparator)
double zscore = sortedMap.lastEntry().getValue().getzScore();