英文:
How to filter dynamically nested list object java 8
问题
如何在Java 8中动态筛选嵌套列表对象
示例:
class Items {
List<Mobile> mobiles;
}
class Mobile {
String mName;
List<Plans> plans;
}
class Plans {
String planId;
String planName;
}
所以,我有3个移动设备(移动设备将是动态的,3或4等等),每个移动设备上有多个计划。如何动态筛选每个移动设备的共同计划?
示例(P1-planId):
项目:
M1 - P1,P2,P3,P4
M2 - P4,P5,P6,P1,P8,P2
M3 - P7,P2,P4,P1,P8,P9,P10
结果:
项目:
M1 - P1,P2,P4
M2 - P1,P2,P4
M3 - P1,P2,P4
英文:
How to filter dynamically nested list object java 8
Example:
class Items {
List<Mobile> mobiles;
}
class Mobile{
String mName;
List<Plans> plans;
}
class Plans{
String planId;
String planName;
}
So, I have 3 mobiles (mobiles will be dynamic 3 or 4..etc) with multiple plans on each mobile device. How to dynamically filter common plan for each mobile device ?
Example(P1-planId) :
Items:
M1 - P1,P2,P3,P4
M2 - P4,P5,P6,P1,P8,P2
M3 - P7,P2,P4,P1,P8,P9,P10
Result:
Items:
M1 - P1,P2,P4
M2 - P1,P2,P4
M3 - P1,P2,P4
答案1
得分: 2
以下是已翻译的代码部分:
获取所有移动设备共有的计划的`Items`内部方法可能如下所示:
public List<Plan> getCommonPlans() {
return mobiles.stream().flatMap(Mobile::streamPlans).distinct()
.filter(p -> mobiles.stream().allMatch(m -> m.hasPlan(p)))
.collect(Collectors.toList());
}
这假设了`Mobile.streamPlans`和`Mobile.hasPlan`方法相当简单。
稍微不同的方法,更高效但可能不太直观,是计算计划并过滤出计数等于移动设备数量的计划:
return mobiles.stream().flatMap(Mobile::streamPlans)
.collect(Collectors.groupingBy(m -> m, Collectors.counting())
.entrySet().stream()
.filter(e -> e.getValue() == mobiles.size())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
英文:
A method inside Items
to get all plans common to all mobiles might look like:
public List<Plan> getCommonPlans() {
return mobiles.stream().flatMap(Mobile::streamPlans).distinct()
.filter(p -> mobiles.stream().allMatch(m -> m.hasPlan(p)))
.collect(Collectors.toList());
}
this assumes Mobile.streamPlans
and Mobile.hasPlan
methods which are pretty trivial.
A slightly different method, more efficient but perhaps not so intuitive, is to count the plans and filter for ones that have counts equal to number of mobiles:
return mobiles.stream().flatMap(Mobile::streamPlans)
.collect(Collectors.groupingBy(m -> m, Collectors.counting())
.entrySet().stream()
.filter(e -> e.getValue() == mobiles.size())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
答案2
得分: 1
首先,获取第一个手机的计划,并且使用 retainAll
方法筛选出所有手机的共同计划。
List<Plans> commonPlans = new ArrayList<>(mobiles.get(0).getPlans());
for (int i = 1; i < mobiles.size(); i++) {
commonPlans.retainAll(mobiles.get(i).getPlans());
}
注意: 确保你为 Plans
类重写了 equals
和 hashCode
方法,并且检查手机列表是否为空。
英文:
First, take plans of the first mobile and retainAll
plans of mobiles from that list.
List<Plans> commonPlans = new ArrayList<>(mobiles.get(0).getPlans());
for (int i = 1; i < mobiles.size(); i++) {
commonPlans.retainAll(mobiles.get(i).getPlans());
}
Note: Make sure you override equals
and hashCode
for Plans
and check for empty mobiles list
答案3
得分: 0
- stream all
Mobile
s, - map each
Mobile
to itsList<Plan>
s - create the union of all plans.
In code, this might look something like this:
HashSet<Plan> initialSet = new HashSet<>(mobiles.get(0).getPlans());
return mobiles.stream()
.map(Mobile::getPlans)
.map(HashSet<Plan>::new)
.reduce(initialSet, (plan1, plan2) -> {
plan1.retainAll(plan2);
return plan1;
});
英文:
A slightly different approach would be to:
- stream all
Mobile
s, - map each
Mobile
to itsList<Plan>
s - create the union of all plans.
In code, this might look something like this:
HashSet<Plan> initialSet = new HashSet<>(mobiles.get(0).getPlans());
return mobiles.stream()
.map(Mobile::getPlans)
.map(HashSet<Plan>::new)
.reduce(initialSet, (plan1, plan2) -> {
plan1.retainAll(plan2);
return plan1;
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论