对两个List进行关联匹配,选择匹配上的记录形成新的List输出

Java 8 Stream Convert  Stream<List<String>> to List<String>

【目标】:对两个集合中的元素通过特定指标进行匹配,重新组合匹配成功的元素。(如下图:)

【说明】:对两个集合 listA、listB 依据 field1 字段进行匹配,若匹配成功,则取出 listA 中的 field0、field1 和 listB 中的 field2 组合成新元素;多个匹配项形成新的 list:commonList.

【关键】:java8 Stream处理: list.stream().*其他操作*().flatMap() 实现合并。

   【关键代码示例】:

【完整代码示例】:

 1     @Data
 2     class Person {
 3         private String userName;
 4         private int bloodVolume;
 5         public Person(String userName, int bloodVolume) {
 6             this.userName = userName;
 7             this.bloodVolume = bloodVolume;
 8         }
 9     }
10 
11     @Data
12     class Rule {
13         private String userName;
14         private String align;
15         public Rule(String userName, String align) {
16             this.userName = userName;
17             this.align = align;
18         }
19     }
20 
21     @Data
22     class Hero {
23         private String userName;
24         private int bloodVolume;
25         private String align;
26         public Hero(String userName, int bloodVolume, String align) {
27             this.userName = userName;
28             this.bloodVolume = bloodVolume;
29             this.align = align;
30         }
31     }
32 
33     @Test
34     public void test(){
35         List<Person> userListA = Arrays.asList(
36                 new Person("关羽", 926),
37                 new Person("赵云", 916),
38                 new Person("张飞", 906),
39                 new Person("许褚", 911));
40         List<Rule> userListB = Arrays.asList(
41                 new Rule("关羽", "字·云长-关公-武财神-汉寿亭侯"),
42                 new Rule("张飞", "字·益德-勇武过人-西乡侯"),
43                 new Rule("刘备", "字·玄德-百折不挠-汉昭烈帝"),
44                 new Rule("赵云", "字·子龙-忠义-永昌亭侯"),
45                 new Rule("周瑜", "字·公瑾-文武兼备-永昌亭侯"),
46                 new Rule("许褚", "字·仲康-勇力绝人-虎侯"));
47 
48         List<Hero> commonList = userListA.stream()
49                 .map((uA) -> {
50                     return userListB.stream()
51                             .filter((uB) -> {
52                                 return StringUtils.equals(uB.getUserName(), uA.getUserName());
53                             })
54                             .map((uB) -> {
55                                 return new Hero(uB.getUserName(), uA.getBloodVolume(), uB.align);
56                             })
57                             .collect(Collectors.toList());
58                 }) // 结果类型 Steam<List<Hero>>
59                 .flatMap(List::stream) // 结果类型 Steam<Hero>
60                 .collect(Collectors.toList()); // 结果类型 List<Hero>
61 
62         System.out.println(JSON.toJSONString(commonList)); 
63         // [{"align":"字·云长-关公-武财神-汉寿亭侯","bloodVolume":926,"userName":"关羽"},
64         // {"align":"字·子龙-忠义-永昌亭侯","bloodVolume":916,"userName":"赵云"},
65         // {"align":"字·益德-勇武过人-西乡侯","bloodVolume":906,"userName":"张飞"},
66         // {"align":"字·仲康-勇力绝人-虎侯","bloodVolume":911,"userName":"许褚"}]
67     }

 看到最后,可能发现,不能完全符合现有需求。

 但是,应该能从其中 获得启示,因为,有了这个处理,就可以处理其他的。比如 这里的 A、B 可以是不同的对象 及 最终的返回结果  commonList 可以是 对象C 的集合(对象C 数据来源于  A、B对象,或 自定义标识值……)。

 通过 对象的属性进行比对取值,记得唯一性,如果出现 一对多,或者 多对多,会出现 乘积的效应,也应根据当前的业务进行考虑,是否需要 进行 去重后再做上述操作。

原文地址:https://www.cnblogs.com/bridgestone29-08/p/13485180.html