如何在Java 8 / Streams中使用HashMap找到满足某些条件的最大键?

huangapple go评论82阅读模式
英文:

How to find max key with some conditions in HashMap using Java 8 / Streams?

问题

假设我有以下数据:

如何在Java 8 / Streams中使用HashMap找到满足某些条件的最大键?

问题:

  1. 我想找到 Pair 为 'AB'、OrderType 为 'Buy' 且状态为 'InProgress' 的最大 orderId 的 zscore。

注意:我将这些数据存储在名为 orderBook 的 HashMap 中,其中键是 orderId,值是 OrderModel(PairName、OrderType、Status、zscore)。

解决方案 1:

int maxOrderId = 0;
getOrderBook().entrySet().stream()
    .filter(e -> e.getValue().getPairName().equals("AB")
                 && e.getValue().getCompletedStatus().equals("InProgress")
                 && 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,但我希望一次性找到。那么,如何使用 Java 8 / streams 在一行中找到最大 OrderId 的 zscore?

是否有比我的代码更好的方法?

英文:

Suppose I have following data :

如何在Java 8 / Streams中使用HashMap找到满足某些条件的最大键?

Question :

  1. I want to find zscore of largest orderId where Pair is 'AB', OrderType is 'Buy' and status is 'InProgress'.

NOTE: I stored this data into HashMap name is orderBook where Key is orderId and Value is OrderModel (PairName, OrderType, Status, zscore).

Solution 1 :

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

output : Order ID : 5, Zscore : -2.5

I can find zscore using above code but I want to find in one go.

So How can I find the zscore of largest OrderId using Java 8 / streams in one line ?

Is there any better way than my code ?

答案1

得分: 5

你要寻找的是 max 方法:

Optional<Entry<Long, Order>> maxIdEntry = getOrderBook()
  .entrySet()
  .stream()
  .filter(/* 你的筛选逻辑 */)
  .max(Comparator.comparing(Entry::getKey));

这会得到一个 Optional,因此可以使用 isPresent()get() 方法,或者使用 ifPresent(Consumer<T> consumer) 方法来处理结果。

英文:

What you're looking for is the max method:

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

This yields an Optional, so either use the isPresent() and get() methods or the ifPresent(Consumer&lt;T&gt; consumer) method for processing the result

答案2

得分: 2

你可以使用Comparator来使用max()函数获取最大的OrderId,并使用Optionalmap来映射zScore

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

You can use max() using Comparator to get largest OrderId and use map of Optional to map zScore .

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

答案3

得分: 2

已有的答案非常出色。还有更多的方法:

使用TreeMap怎么样?它能够保持键的排序。只要键是例如String,甚至不需要传递Comparator

// 将HashMap复制为TreeMap
NavigableMap<String, Order> navigableMap = new TreeMap<>(getOrderBook());

// 删除不需要的条目(反转条件)
navigableMap.entrySet().removeIf(e ->
     !e.getValue().getPairName().equals("AB") ||
     !e.getValue().getCompletedStatus().equals("InProgress") ||
     !e.getValue().getOrderType().equals("Buy"));

// NavigableMap::lastEntry 获取具有最高键的条目(通过比较器)
double zscore = sortedMap.lastEntry().getValue().getzScore();
英文:

The already existing answer are excellent. There are more ways:

How about using TreeMap which is able to keep the keys sorted? As long as the key is ex. a String, you don't even need to pass a Comparator.

// create a copy of HashMap as a TreeMap
NavigableMap&lt;String, Order&gt; navigableMap = new TreeMap&lt;&gt;(getOrderBook());

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

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

huangapple
  • 本文由 发表于 2020年8月27日 16:51:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63612490.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定