java stream Collectors.groupingBy()多个字段

时间:2018-06-15 08:54:59

标签: 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();

完美无缺。但我想找到重复的不仅仅是名字,还有名称+值+键

  

这意味着如果name + value + key相同,则重复。

我正在寻找Collectors.groupingBy()

react-motion

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

3 个答案:

答案 0 :(得分:4)

而不是

.collect(Collectors.groupingBy(ServiceCharacteristicDto::getName, Collectors.counting()))

你可以写

.collect(Collectors.groupingBy(s->s.getName()+'-'+s.getValue()+'-'+s.getKey(), Collectors.counting()))

答案 1 :(得分:3)

您可以将ServiceCharacteristicDto::getName替换为:

x -> x.getName() + x.getValue() + x.getKey()

使用lambda而不是方法引用。

但是也想到findFirst在这里实际意味着什么......你正在收集一个没有遭遇顺序的HashMap,流式传输它的条目并获得第一个元素 - 不管是什么。你明白这个findFirst可以在不同的输入上给出不同的结果,对吗?即使重新调整HashMap,也可能会返回不同的findFirst结果。

修改

因为String concat而远离可能的非故意重复,你可以使用:

x -> Arrays.asList(x.getName(), x.getValue(), x.getKey())

答案 2 :(得分:2)

以下为我效劳:

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}

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

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