如何将多个列表与流和lambda组合起来,以指示哪里存在重复列表

如何将多个列表与流和lambda组合起来,以指示哪里存在重复列表,lambda,java-8,java-stream,Lambda,Java 8,Java Stream,我正在尝试使用streams和Lambda将多个集合简化为单个集合。但是,我需要指出重复命中发生的位置 我基本上有以下情况: 客户集合1(所有人) 第2集展望 Person 1 (Mike) Person 2 (Wilbur) Person 3 (Joe) 收集3名雇员 Person 1 (Mike) Person 2 (Tony) Person 3 (Sue) Person 4 (Joe) 我想将这个集合转化为一个新的领域,我可以使用Map来完成这个领域——我迷路的地方实际上是如何将它展平

我正在尝试使用streams和Lambda将多个集合简化为单个集合。但是,我需要指出重复命中发生的位置

我基本上有以下情况:

客户集合1(所有人)

第2集展望

Person 1 (Mike)
Person 2 (Wilbur)
Person 3 (Joe)
收集3名雇员

Person 1 (Mike)
Person 2 (Tony)
Person 3 (Sue)
Person 4 (Joe)
我想将这个集合转化为一个新的领域,我可以使用Map来完成这个领域——我迷路的地方实际上是如何将它展平,这样最终的结果会是这样的

收藏

Person 1 (Tom, "Customer")
Person 2 (Bob, "Customer")
Person 3 (Joe, "Customer, Prospect, Employee")
Person 4 (Mike, "Prospect, Employee")
Person 5 (Wilbur, "Prospect")
Person 6 (Tony, "Employee")
Person 7 (Sue, "Employee")  
我只是计划创建一个字符串值来直观地表示它们所属的区域

谢谢

[编辑]

根据下面的建议,我可以通过这种方式测试解决方案

类TestOutplatmap{ 公开无效测试(){


我看不出它在哪里连接不正确。

由于您有多个不同类型的集合,每个集合都应该有一些标识符。因此,将输入表示为集合映射的最佳方法是,映射的键表示集合的类型,如客户、潜在客户和员工

现在,假设您有一个
映射,
您需要按集合的每个元素进行分组,并跟踪关联的键。为此,您需要使用flatmap。 以下代码应该可以工作:

    Map<String, Collection<Person>> map = new HashMap<>();
    map.put("Customer", ...);
    map.put("Prospect", ...;
    map.put("Employee", ...;

    Map<Person, String> output = map
        .entrySet()
        .stream()
        .flatMap(t -> t.getValue().stream().map(g -> new Pair<>(t.getKey(), g)))
        .collect(Collectors.toMap(
                t -> t.getValue(), u -> u.getKey(), (x, y) -> x + ", " + y));
Map Map=newhashmap();
地图放置(“客户”,…);
map.put(“前景”)。。。;
map.put(“员工”。。。;
地图输出=地图
.entrySet()
.stream()
.flatMap(t->t.getValue().stream().map(g->newpair(t.getKey(),g)))
.collect(collector.toMap)(
t->t.getValue(),u->u.getKey(),(x,y)->x+,“+y”);

请注意,Pair类是从中使用的。

您可以尝试分组,使用下游收集器将组转换为字符串,如下所示:

        Map<Person, String> result = map
        .entrySet()
        .stream()
        .flatMap(e -> e.getValue().stream().map(v -> new AbstractMap.SimpleEntry<>(v,e.getKey())))
        .collect(
            Collectors.groupingBy(Map.Entry::getKey,         // group Map.Entry by key
                Collectors.mapping(Map.Entry::getValue,      // for each group, convert Map.Entry into the value 
                    Collectors.joining(","))));              // convert the values into a comma-delimited String
        Map<Person, String> result = map
        .entrySet()
        .stream()
        .flatMap(e -> e.getValue().stream().map(v -> new AbstractMap.SimpleEntry<>(v,e.getKey())))
        .collect(Collectors.groupingBy(
                Map.Entry::getKey,
                Collectors.mapping(Map.Entry::getValue,
                        Collectors.collectingAndThen(
                                Collectors.toSet(), x -> String.join(",",x)))));
通过以下设置

        Map<String, Collection<Person>> map = new HashMap<>();
        Person person1 = new Person("Person1");
        Person person2 = new Person("Person2");
        map.put("Customer", Arrays.asList(person1, person2));
        map.put("Prospect", Arrays.asList(person1));
        map.put("Employee", Arrays.asList(person2, person2));
Map Map=newhashmap();
人员1=新人员(“人员1”);
人员2=新人员(“人员2”);
map.put(“Customer”,Arrays.asList(person1,person2));
map.put(“Prospect”,Arrays.asList(person1));
map.put(“Employee”,Arrays.asList(person2,person2));

我得到了
{Person1=Customer,Prospect,Person2=Employee,Customer}

实际上这不起作用。它几乎起作用了。我得到了以下结果,例如:Joe,“Customer,Customer,Customer”。我确实在映射中得到了键的正确值。嗯,你的代码不正确。你正在创建3个集合,p1、p2、p3。但是总是在p1中添加元素。尝试更正它,你会得到正确的输出。是的-我在另一篇文章中看到了这一点。谢谢。谢谢你的提示-不幸的是,这两个都给了我一个编译错误r在collect的“推断变量K有不兼容的边界”和这一个“collect的类型(CollectorTanks,@Purring鸽子,我为
map
输入了错误的类型。我更正了我的回答这很奇怪-当我运行第一个示例时,我得到了相同的结果…收集器一遍又一遍地连接相同的字符串…Joe”Customer,Customer,Customer“而不是我所期望的Joe“Customer,Prospect,Employee”。第二个示例将字符串折叠为“Customer”。在第一个示例中,您应该看到重复键的唯一方式是,如果同一个人多次出现在同一列表中。请检查
equals()
Person
类中的
函数——也许你的
Person
的所有实例在逻辑上都是相等的?@purringbide,我更新了我的答案,以说明我是如何设置的。我使用了你在示例中提供的
Person
的实现。顺便说一句,你应该更改
hashCode
函数。
        Map<Person, String> result = map
        .entrySet()
        .stream()
        .flatMap(e -> e.getValue().stream().map(v -> new AbstractMap.SimpleEntry<>(v,e.getKey())))
        .collect(
            Collectors.groupingBy(Map.Entry::getKey,         // group Map.Entry by key
                Collectors.mapping(Map.Entry::getValue,      // for each group, convert Map.Entry into the value 
                    Collectors.joining(","))));              // convert the values into a comma-delimited String
        Map<Person, String> result = map
        .entrySet()
        .stream()
        .flatMap(e -> e.getValue().stream().map(v -> new AbstractMap.SimpleEntry<>(v,e.getKey())))
        .collect(Collectors.groupingBy(
                Map.Entry::getKey,
                Collectors.mapping(Map.Entry::getValue,
                        Collectors.collectingAndThen(
                                Collectors.toSet(), x -> String.join(",",x)))));
        Map<String, Collection<Person>> map = new HashMap<>();
        Person person1 = new Person("Person1");
        Person person2 = new Person("Person2");
        map.put("Customer", Arrays.asList(person1, person2));
        map.put("Prospect", Arrays.asList(person1));
        map.put("Employee", Arrays.asList(person2, person2));