英文:
How to filter TreeMap<MyKey, Map<Key2,List<Kids>>> ,
问题
FundingRank 和 ScoreBucket 是枚举,但本质上是 int
枚举 FundingRank {
LESS_THAN_0(0),
LESS_THAN_1(1),
LESS_THAN_100(100);
private final int rank;
FundingRank(int i) {
this.rank = i;
}
}
枚举 ScoreBucket {
MORE_THAN_1000(1000),
MORE_THAN_500(1000),
MORE_THAN_100(100),
MORE_THAN_10(10);
private final int bucket;
ScoreBucket(int i) {
this.bucket = i;
}
}
我有一个保存数据的 `TreeMap<FundingRank, TreeMap<ScoreBucket, List<Kids>>>`,数据如下:
fundingRank scoreBucket List<Kids>
0 1000 List(有 1 个元素)
500 List(有 2 个元素)
100 List(有 4 个元素)
10 List(有 3 个元素)
1 1000 List(有 4 个元素)
500 List(有 7 个元素)
100 List(有 4 个元素)
10 List(有 3 个元素)
现在,我想要找到最小的 `fundingRank` 和最大的 `scoreBucket`,并且至少有 5 个孩子,如果没有的话,就找最小的 `fundingRank` 和最大的 `scoreBucket`
我尝试以下代码:
myMap.entrySet().stream()
.filter(e -> e.getValue().entrySet().stream()
.filter(e2 -> e2.getValue().size() >= 5)
.findFirst());
输出排序后的地图如下:
1 500 List(有 7 个元素)
0 100 List(有 4 个元素)
1 1000 List(有 4 个元素)
1 100 List(有 4 个元素)
0 10 List(有 3 个元素)
...
所以,我试图对 TreeMap<Int, TreeMap<Int, List<Kid>>> 进行排序,排序顺序定义为最小的 FundingRank 和最大的 ScoreBucket(如果桶里有 5 个孩子,这意味着如果有任何其他更小的桶,其中有更多的孩子,那么较高分数的桶将获胜,或者如果有一个更大的 FundingRank,其中有更高的桶大小和更多的孩子,仍然是较低的 fundingBucket 行获胜,如果它达到了 5 个孩子的阈值),然后选择第一行。希望现在清楚了。
英文:
FundingRank and SourceBucket are enums but essentially int
enum FundingRank {
LESS_THAN_0(0),
LESS_THAN_1(1),
LESS_THAN_100(100);
private final int rank;
FundingRank(int i) {
this.rank = i;
}
}
enum ScoreBucket {
MORE_THAN_1000(1000),
MORE_THAN_500(1000),
MORE_THAN_100(100),
MORE_THAN_10(10);
private final int bucket;
ScoreBucket(int i) {
this.bucket = i;
}
}
I have a TreeMap<FundingRank, TreeMap<scoreBucket, List<Kids>> >
holding data like
fundingRank scoreBucket List<Kids>
0 1000 List(with 1 elements)
500 List(with 2 elements)
100 List(with 4 elements)
10 List(with 3 elements)
1 1000 List(with 4 elements)
500 List(with 7 elements)
100 List(with 4 elements)
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
myMap.entrySet().stream()
.filter(e -> e.getvalue().entryset().stream()
.filter(e2 ->e2.getvalue().size()).findfirst();
Output sorted map like this:
1 500 List(with 7 elements)
0 100 List(with 4 elements)
1 1000 List(with 4 elements)
1 100 List(with 4 elements)
0 10 List(with 3 elements)
...
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
来查找它:
Optional<Map.Entry<FundingRank, Map.Entry<ScoreBucket, Integer>>> triplet =
outerMap.entrySet().stream()
.flatMap(outerEntry -> outerEntry.getValue().entrySet().stream()
.map(innerEntry -> Map.entry(
outerEntry.getKey(),
Map.entry(innerEntry.getKey(), innerEntry.getValue().size()))))
.min(Comparator.comparingInt(t -> t.getValue().getValue() >= 5 ? 0 : 1)
.thenComparing(t -> t.getKey())
.thenComparing(t -> t.getValue().getKey(), Comparator.reverseOrder())
.thenComparing(t -> t.getValue().getValue(), Comparator.reverseOrder()));
triplet.ifPresent(it -> /* 对三元组执行操作 */);
这将创建Map.Entry<FundingRank,Map.Entry<ScoreBucket,Integer>>
格式的三元组,并根据给定的Comparator
查找最小的三元组,符合您的要求。
我们在Stream.min
中使用了一个Comparator
,它首先按0
或1
进行排序,这是一个指示是否有超过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:
Optional<Map.Entry<FundingRank, Map.Entry<ScoreBucket, Integer>>> triplet =
outerMap.entrySet().stream()
.flatMap(outerEntry -> outerEntry.getValue().entrySet().stream()
.map(innerEntry -> Map.entry(
outerEntry.getKey(),
Map.entry(innerEntry.getKey(), innerEntry.getValue().size()))))
.min(Comparator.comparingInt(t -> t.getValue().getValue() >= 5 ? 0 : 1)
.thenComparing(t -> t.getKey())
.thenComparing(t -> t.getValue().getKey(), Comparator.reverseOrder())
.thenComparing(t -> t.getValue().getValue(), Comparator.reverseOrder()));
triplet.ifPresent(it -> /* do something with the triplet */);
This creates triplets as Map.Entry<FundingRank, Map.Entry<ScoreBucket, Integer>>
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(...)
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论