java stream Collectors.groupingBy() 多个字段

mbr*_*brc 5 java java-8 java-stream

Stream<Map.Entry<String, Long>> duplicates = notificationServiceOrderItemDto.getService()
    .getServiceCharacteristics()
    .stream()
    .collect(
        Collectors.groupingBy(
            ServiceCharacteristicDto::getName, Collectors.counting()
        )
     )
     .entrySet()
     .stream()
     .filter(e -> e.getValue() > 1);

Optional<String> dupName = duplicates.map(Map.Entry::getKey).findFirst();
Run Code Online (Sandbox Code Playgroud)

工作完美。但我想找到重复的不仅有名字而且还有名字+值+键

这意味着如果名称 + 值 + 键相同,则这是重复的。

我正在寻找 Collectors.groupingBy()

http://www.technicalkeeda.com/java-8-tutorials/java-8-stream-grouping

但我找不到正确的解决方案

Ash*_*Jha 5

以下对我有用:

public class Groupingby
{
    static class Obj{
        String name;
        String value;
        String key;

        Obj(String name, String val, String key)
        {
            this.name = name;
            this.value = val;
            this.key = key;
        }
    }

    public static void main(String[] args)
    {
        List<Obj> objects = new ArrayList<>();

        objects.add(new Obj("A", "K", "Key1"));
        objects.add(new Obj("A", "K", "Key1"));
        objects.add(new Obj("A", "X", "Key1"));
        objects.add(new Obj("A", "Y", "Key2"));

        Map<List<String>, Long> collected = objects.stream().collect(Collectors.groupingBy(x -> Arrays.asList(x.name, x.value, x.key), Collectors.counting()));

        System.out.println(collected);
    }

}

// Output
// {[A, K, Key1]=2, [A, Y, Key2]=1, [A, X, Key1]=1}
Run Code Online (Sandbox Code Playgroud)

请注意,我使用属性列表进行分组,而不是属性的字符串连接。这也适用于非字符串属性。

如果您正在执行字符串连接,您可能会遇到一些极端情况,例如属性 (A, BC, D) 和 (AB, C, D) 将产生相同的字符串。

  • @Lino 虽然你是对的,但是关于这个连接 * 必须 * 输出什么的决定完全由 OP 来决定:) (2认同)

Era*_*ran 4

代替

.collect(Collectors.groupingBy(ServiceCharacteristicDto::getName, Collectors.counting()))
Run Code Online (Sandbox Code Playgroud)

你可以写

.collect(Collectors.groupingBy(s->s.getName()+'-'+s.getValue()+'-'+s.getKey(), Collectors.counting()))
Run Code Online (Sandbox Code Playgroud)

  • 这可能会产生不正确的结果。示例:**name=aa value=bb key=cc** 的实例将错误地成为 **name=aab value=b key=cc** 的实例的重复项 (4认同)
  • 好吧,但是为什么要引入一个“可以简单解决”的问题,当你可以简单地使用没有任何内容的 `s -&gt; Arrays.asList(s.getName(), s.getValue(), s.getKey())` 时首先是这样的问题吗?它甚至可能比重复进行字符串连接更有效……如果您使用 Java 9 并且可以排除“null”值,您还可以使用“List.of(...)”,这可能会更有效。 (2认同)