重复数据消除Java8流
这里是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) {}
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());