英文:
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 
Mobiles, - map each 
Mobileto 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 
Mobiles, - map each 
Mobileto 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;
	});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论