如何在Java 8中动态过滤嵌套列表对象

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

How to filter dynamically nested list object java 8

问题

如何在Java 8中动态筛选嵌套列表对象

示例:

  1. class Items {
  2. List<Mobile> mobiles;
  3. }
  4. class Mobile {
  5. String mName;
  6. List<Plans> plans;
  7. }
  8. class Plans {
  9. String planId;
  10. String planName;
  11. }

所以,我有3个移动设备(移动设备将是动态的,3或4等等),每个移动设备上有多个计划。如何动态筛选每个移动设备的共同计划?

示例(P1-planId):

  1. 项目:
  2. M1 - P1,P2,P3,P4
  3. M2 - P4,P5,P6,P1,P8,P2
  4. M3 - P7,P2,P4,P1,P8,P9,P10

结果:

  1. 项目:
  2. M1 - P1,P2,P4
  3. M2 - P1,P2,P4
  4. M3 - P1,P2,P4
英文:

How to filter dynamically nested list object java 8

Example:

  1. class Items {
  2. List&lt;Mobile&gt; mobiles;
  3. }
  4. class Mobile{
  5. String mName;
  6. List&lt;Plans&gt; plans;
  7. }
  8. class Plans{
  9. String planId;
  10. String planName;
  11. }

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) :

  1. Items:
  2. M1 - P1,P2,P3,P4
  3. M2 - P4,P5,P6,P1,P8,P2
  4. M3 - P7,P2,P4,P1,P8,P9,P10

Result:

  1. Items:
  2. M1 - P1,P2,P4
  3. M2 - P1,P2,P4
  4. M3 - P1,P2,P4

答案1

得分: 2

以下是已翻译的代码部分:

  1. 获取所有移动设备共有的计划的`Items`内部方法可能如下所示
  2. public List<Plan> getCommonPlans() {
  3. return mobiles.stream().flatMap(Mobile::streamPlans).distinct()
  4. .filter(p -> mobiles.stream().allMatch(m -> m.hasPlan(p)))
  5. .collect(Collectors.toList());
  6. }
  7. 这假设了`Mobile.streamPlans``Mobile.hasPlan`方法相当简单
  8. 稍微不同的方法更高效但可能不太直观是计算计划并过滤出计数等于移动设备数量的计划
  9. return mobiles.stream().flatMap(Mobile::streamPlans)
  10. .collect(Collectors.groupingBy(m -> m, Collectors.counting())
  11. .entrySet().stream()
  12. .filter(e -> e.getValue() == mobiles.size())
  13. .map(Map.Entry::getKey)
  14. .collect(Collectors.toList());
英文:

A method inside Items to get all plans common to all mobiles might look like:

  1. public List&lt;Plan&gt; getCommonPlans() {
  2. return mobiles.stream().flatMap(Mobile::streamPlans).distinct()
  3. .filter(p -&gt; mobiles.stream().allMatch(m -&gt; m.hasPlan(p)))
  4. .collect(Collectors.toList());
  5. }

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:

  1. return mobiles.stream().flatMap(Mobile::streamPlans)
  2. .collect(Collectors.groupingBy(m -&gt; m, Collectors.counting())
  3. .entrySet().stream()
  4. .filter(e -&gt; e.getValue() == mobiles.size())
  5. .map(Map.Entry::getKey)
  6. .collect(Collectors.toList());

答案2

得分: 1

首先,获取第一个手机的计划,并且使用 retainAll 方法筛选出所有手机的共同计划。

  1. List<Plans> commonPlans = new ArrayList<>(mobiles.get(0).getPlans());
  2. for (int i = 1; i < mobiles.size(); i++) {
  3. commonPlans.retainAll(mobiles.get(i).getPlans());
  4. }

注意: 确保你为 Plans 类重写了 equalshashCode 方法,并且检查手机列表是否为空。

英文:

First, take plans of the first mobile and retainAll plans of mobiles from that list.

  1. List&lt;Plans&gt; commonPlans = new ArrayList&lt;&gt;(mobiles.get(0).getPlans());
  2. for (int i = 1; i &lt; mobiles.size(); i++) {
  3. commonPlans.retainAll(mobiles.get(i).getPlans());
  4. }

Note: Make sure you override equals and hashCode for Plans and check for empty mobiles list

答案3

得分: 0

  • stream all Mobiles,
  • map each Mobile to its List&lt;Plan&gt;s
  • create the union of all plans.

In code, this might look something like this:

  1. HashSet&lt;Plan&gt; initialSet = new HashSet&lt;&gt;(mobiles.get(0).getPlans());
  2. return mobiles.stream()
  3. .map(Mobile::getPlans)
  4. .map(HashSet&lt;Plan&gt;::new)
  5. .reduce(initialSet, (plan1, plan2) -&gt; {
  6. plan1.retainAll(plan2);
  7. return plan1;
  8. });

<kbd>Ideone demo</kbd>

英文:

A slightly different approach would be to:

  • stream all Mobiles,
  • map each Mobile to its List&lt;Plan&gt;s
  • create the union of all plans.

In code, this might look something like this:

  1. HashSet&lt;Plan&gt; initialSet = new HashSet&lt;&gt;(mobiles.get(0).getPlans());
  2. return mobiles.stream()
  3. .map(Mobile::getPlans)
  4. .map(HashSet&lt;Plan&gt;::new)
  5. .reduce(initialSet, (plan1, plan2) -&gt; {
  6. plan1.retainAll(plan2);
  7. return plan1;
  8. });

<kbd>Ideone demo</kbd>

huangapple
  • 本文由 发表于 2020年8月8日 13:12:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63312068.html
匿名

发表评论

匿名网友

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

确定