如何过滤 TreeMap>>,

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

How to filter TreeMap<MyKey, Map<Key2,List<Kids>>> ,

问题

  1. FundingRank ScoreBucket 是枚举但本质上是 int
  2. 枚举 FundingRank {
  3. LESS_THAN_0(0),
  4. LESS_THAN_1(1),
  5. LESS_THAN_100(100);
  6. private final int rank;
  7. FundingRank(int i) {
  8. this.rank = i;
  9. }
  10. }
  11. 枚举 ScoreBucket {
  12. MORE_THAN_1000(1000),
  13. MORE_THAN_500(1000),
  14. MORE_THAN_100(100),
  15. MORE_THAN_10(10);
  16. private final int bucket;
  17. ScoreBucket(int i) {
  18. this.bucket = i;
  19. }
  20. }
  21. 我有一个保存数据的 `TreeMap<FundingRank, TreeMap<ScoreBucket, List<Kids>>>`数据如下
  22. fundingRank scoreBucket List<Kids>
  23. 0 1000 List( 1 个元素)
  24. 500 List( 2 个元素)
  25. 100 List( 4 个元素)
  26. 10 List( 3 个元素)
  27. 1 1000 List( 4 个元素)
  28. 500 List( 7 个元素)
  29. 100 List( 4 个元素)
  30. 10 List( 3 个元素)
  31. 现在我想要找到最小的 `fundingRank` 和最大的 `scoreBucket`并且至少有 5 个孩子如果没有的话就找最小的 `fundingRank` 和最大的 `scoreBucket`
  32. 我尝试以下代码
  33. myMap.entrySet().stream()
  34. .filter(e -> e.getValue().entrySet().stream()
  35. .filter(e2 -> e2.getValue().size() >= 5)
  36. .findFirst());
  37. 输出排序后的地图如下
  38. 1 500 List( 7 个元素)
  39. 0 100 List( 4 个元素)
  40. 1 1000 List( 4 个元素)
  41. 1 100 List( 4 个元素)
  42. 0 10 List( 3 个元素)
  43. ...
  44. 所以我试图对 TreeMap<Int, TreeMap<Int, List<Kid>>> 进行排序排序顺序定义为最小的 FundingRank 和最大的 ScoreBucket如果桶里有 5 个孩子这意味着如果有任何其他更小的桶其中有更多的孩子那么较高分数的桶将获胜或者如果有一个更大的 FundingRank其中有更高的桶大小和更多的孩子仍然是较低的 fundingBucket 行获胜如果它达到了 5 个孩子的阈值),然后选择第一行希望现在清楚了
英文:

FundingRank and SourceBucket are enums but essentially int

  1. enum FundingRank {
  2. LESS_THAN_0(0),
  3. LESS_THAN_1(1),
  4. LESS_THAN_100(100);
  5. private final int rank;
  6. FundingRank(int i) {
  7. this.rank = i;
  8. }
  9. }
  10. enum ScoreBucket {
  11. MORE_THAN_1000(1000),
  12. MORE_THAN_500(1000),
  13. MORE_THAN_100(100),
  14. MORE_THAN_10(10);
  15. private final int bucket;
  16. ScoreBucket(int i) {
  17. this.bucket = i;
  18. }
  19. }

I have a TreeMap&lt;FundingRank, TreeMap&lt;scoreBucket, List&lt;Kids&gt;&gt; &gt; holding data like

  1. fundingRank scoreBucket List&lt;Kids&gt;
  2. 0 1000 List(with 1 elements)
  3. 500 List(with 2 elements)
  4. 100 List(with 4 elements)
  5. 10 List(with 3 elements)
  6. 1 1000 List(with 4 elements)
  7. 500 List(with 7 elements)
  8. 100 List(with 4 elements)
  9. 10 List(with 3 elements)

Now I , want to find element minimum fundingRank and maximum scoreBucket with minimum 5 kids, if not then minimum fundingRank and maximum scoreBucket

  1. myMap.entrySet().stream()
  2. .filter(e -&gt; e.getvalue().entryset().stream()
  3. .filter(e2 -&gt;e2.getvalue().size()).findfirst();
  4. Output sorted map like this:
  5. 1 500 List(with 7 elements)
  6. 0 100 List(with 4 elements)
  7. 1 1000 List(with 4 elements)
  8. 1 100 List(with 4 elements)
  9. 0 10 List(with 3 elements)
  10. ...

So, I am trying to sort the TreeMap<Int, TreeMap<Int, List<Kid>>>, the sort order is defined as MinFunding rank and max ScoreBucket (with threshold 5, if bucket has 5 kids, meaning if there is any other smaller bucket with more kids, the higher score bucket wins, or if there is a bigger FundingRank with higher bucket size and more kids, still the lower fundingBucket row wins if it meets 5 kids threshold), then pick up the 1st row
hope it is clear now

答案1

得分: 2

如果您想找到具有最小FundingRank和最大ScoreBucket的三元组[fundingRank,scoreBucket,list_Kids],但仅考虑拥有超过5个孩子的三元组,您可以流式处理外部和内部映射的条目,并使用自定义的Comparator来查找它:

  1. Optional<Map.Entry<FundingRank, Map.Entry<ScoreBucket, Integer>>> triplet =
  2. outerMap.entrySet().stream()
  3. .flatMap(outerEntry -> outerEntry.getValue().entrySet().stream()
  4. .map(innerEntry -> Map.entry(
  5. outerEntry.getKey(),
  6. Map.entry(innerEntry.getKey(), innerEntry.getValue().size()))))
  7. .min(Comparator.comparingInt(t -> t.getValue().getValue() >= 5 ? 0 : 1)
  8. .thenComparing(t -> t.getKey())
  9. .thenComparing(t -> t.getValue().getKey(), Comparator.reverseOrder())
  10. .thenComparing(t -> t.getValue().getValue(), Comparator.reverseOrder()));
  11. triplet.ifPresent(it -> /* 对三元组执行操作 */);

这将创建Map.Entry<FundingRank,Map.Entry<ScoreBucket,Integer>>格式的三元组,并根据给定的Comparator查找最小的三元组,符合您的要求。

我们在Stream.min中使用了一个Comparator,它首先按01进行排序,这是一个指示是否有超过5个孩子的标志。如果有超过5个孩子,则该标志为0,以便首先显示具有超过5个孩子的三元组。然后,比较器按升序排序FundingRank,然后按降序排序ScoreBucket,最后,在平局的情况下,按实际孩子数量降序排序(以防万一)。

在这里,我使用了Java 9+的Map.entry(...)方法来创建条目。如果您使用的是Java 8,应该使用new AbstractMap.SimpleEntry(...)来创建条目。

英文:

If you want to find the [fundingRank, scoreBucket, list_Kids] triplet with min FundingRank and max ScoreBucket, but only considering triplets with more than 5 kids, you could stream the entries of your outer and inner maps and use a custom Comparator to find it:

  1. Optional&lt;Map.Entry&lt;FundingRank, Map.Entry&lt;ScoreBucket, Integer&gt;&gt;&gt; triplet =
  2. outerMap.entrySet().stream()
  3. .flatMap(outerEntry -&gt; outerEntry.getValue().entrySet().stream()
  4. .map(innerEntry -&gt; Map.entry(
  5. outerEntry.getKey(),
  6. Map.entry(innerEntry.getKey(), innerEntry.getValue().size()))))
  7. .min(Comparator.comparingInt(t -&gt; t.getValue().getValue() &gt;= 5 ? 0 : 1)
  8. .thenComparing(t -&gt; t.getKey())
  9. .thenComparing(t -&gt; t.getValue().getKey(), Comparator.reverseOrder())
  10. .thenComparing(t -&gt; t.getValue().getValue(), Comparator.reverseOrder()));
  11. triplet.ifPresent(it -&gt; /* do something with the triplet */);

This creates triplets as Map.Entry&lt;FundingRank, Map.Entry&lt;ScoreBucket, Integer&gt;&gt; and finds the min triplet, according to the given Comparator, which (I hope) fulfils your requirements.

We're using a Comparator in Stream.min that first sorts by either 0 or 1, which is a flag that specifies whether there are more than 5 kids or not. This flag is 0 if there are more than 5 kids, so that triplets with more than 5 kids appear first. Then, the comparator sorts by FundingRank ascending, then by ScoreBucket descending and, finally, if there is a tie, it's broken by the actual number of kids descending (just in case).

Here I've used the Java 9+'s Map.entry(...) method to create entries. If you're on Java 8, you should create entries with new AbstractMap.SimpleEntry(...).

huangapple
  • 本文由 发表于 2020年10月15日 11:15:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64364337.html
匿名

发表评论

匿名网友

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

确定