重复数据消除Java8流

重复数据消除Java8流,java,collections,java-8,java-stream,Java,Collections,Java 8,Java Stream,这里是Java8。我有一个方法checkDupeKeys,它将三个不同的SortedMap实例作为其参数,并且需要验证没有两个SortedMap实例具有相同的键。我迄今为止最好的尝试是: private void checkDupeKeys(SortedMap<String, Fizz> fizzes, SortedMap<String, Buzz> buzzes, SortedMap<String, Foobar> foobars) {}

这里是Java8。我有一个方法
checkDupeKeys
,它将三个不同的
SortedMap
实例作为其参数,并且需要验证没有两个
SortedMap
实例具有相同的键。我迄今为止最好的尝试是:

private void checkDupeKeys(SortedMap<String, Fizz> fizzes, SortedMap<String, Buzz> buzzes,
        SortedMap<String, Foobar> foobars) {}
    List<String> keyNames = new ArrayList<>();

    keyNames.addAll(fizzes.keySet().stream().collect(Collectors.toList()));
    keyNames.addAll(buzzes.keySet().stream().collect(Collectors.toList()));
    keyNames.addAll(foobars.keySet().stream().collect(Collectors.toList()));

    if(keyNames.size() > keyNames.stream().collect(Collectors.toSet()).size()) {
        throw new IllegalArgumentException("Duplicate key names are not allowed.");
    }
}

如何修改我的(非静态)
checkDupeKeys
方法以引发符合此条件的异常?也就是说,我如何访问流中哪些密钥是彼此重复的。我相信我可以通过使用较旧的Java collections API艰难地做到这一点,但在这个解决方案中,效率和利用Java 8 API对我来说很重要。

如果不太使用Java 8的函数习惯用法,我只需对每个比较进行比较(总共3个)

见以下代码草案:

private void checkDupeKeys(SortedMap<String, Fizz> fizzes, 
    SortedMap<String, Buzz> buzzes, 
    SortedMap<String, Foobar> foobars) {

    // copies the key set
    Set<String> fizBuzSet = new HashSet<>(fizzes.keySet());

    // this removes all elements of the set that aren't present in the given key set
    fizBuzSet.retainAll(buzzes.keySet());

    // aggregating dupes if needed
    Map<String, Collection<String>> dupes = new HashMap<>();
    // flag to throw exception if needed
    boolean areThereDupes = false;

    if (!fizBuzSet.isEmpty()) {
        areThereDupes = true;
        // TODO log fizBuzSet as set of duplicates between fizzes and buzzes
        // or...
        dupes.put("Fizzes vs Buzzes", fizBuzSet);
    }
    // TODO repeat with fizzes vs foobars, then again with buzzes vs foobars

    // you can either log the dupes separately, or use a Map<String,Collection<String>> where the  
    // keys represent a compound of the two SortedMaps being compared and the values represent the actual duplicates  
    // e.g...
    if (areThereDupes) {
        // TODO throw exception with dupes map representation in message
    }

}
private void checkDupeKeys(分类地图泡沫、,
分拣地图蜂鸣器,
分类地图(单条){
//复制密钥集
Set fizbuzzet=newhashset(fizzes.keySet());
//这将删除给定密钥集中不存在的集合的所有元素
fizBuzSet.retainAll(蜂鸣器键集());
//如果需要,聚合复制
Map dupes=new HashMap();
//标记以在需要时引发异常
布尔值aretrerepes=false;
如果(!fizBuzSet.isEmpty()){
是否重复=正确;
//TODO将FizBuzzset记录为气泡和蜂鸣器之间的一组重复项
//或者。。。
重复。放置(“嘶嘶声vs蜂鸣器”,嘶嘶声);
}
//用嘶嘶声对foobars重复TODO,然后用蜂鸣器对foobars再次重复
//您可以单独记录复制,也可以使用
//键表示正在比较的两个分类映射的复合,值表示实际的重复
//例如。。。
如果(有重复){
//TODO在消息中引发重复映射表示的异常
}
}

您要做的第一件事是将所有密钥收集到一个流中:

 Stream<String> keys = Stream.of(
       fizzes.keySet().stream(), 
       buzzes.keySet().stream(), 
       foobars.keySet().stream())
    .flatMap(s -> s);
您可以过滤计数大于1的条目:

 Set<String> duplicates = counts.entrySet().stream()
            .filter( e -> e.getValue() > 0)
            .map(Entry::getKey)
            .collect(Collectors.toSet());
Set duplicates=counts.entrySet().stream()
.filter(e->e.getValue()>0)
.map(条目::getKey)
.collect(收集器.toSet());

如果此集合不是空的,则引发异常。

为什么不适用于您,为什么不在添加密钥时引发异常?介意分享一下使用您已经尝试过的旧Java集合的艰难方式吗?可能的重复并没有达到问题中所期望的效果。请看一看问题中的异常部分。@nullpointer是的,这不会引发异常,但如果您看注释,它确实会给出如何通过比较聚合重复项的建议(这实际上是OP想要的)。反过来,这可以作为异常消息传递,也就是说,如果映射不是空的,则可以抛出具有映射表示形式的异常。@我编辑了nullpointer以证实映射和异常抛出,希望它现在更具体一些。
 Map<String, Long> counts = keys.collect(
     Collectors.groupingBy(Function.identity(),
     Collectors.counting()));
 Set<String> duplicates = counts.entrySet().stream()
            .filter( e -> e.getValue() > 0)
            .map(Entry::getKey)
            .collect(Collectors.toSet());