Java 8在这里。我有一个方法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.");
}
}
我相信这是有效的,但是很可能有更好的方法(效率等)。
我主要担心的是,这种方法不允许我识别哪些键名是重复的。我理想地喜欢异常消息:
Duplicate key names are not allowed. You have the following duplicate key names: (1) fizzes["derp"] and buzzes["derp"]. (2) fizzes["flim"] and foobars["flim"]. (3) buzzes["flam"] and foobars["flam"].
如何修改我的(非静态)checkDupeKeys
方法以抛出符合此条件的异常?也就是说,如何访问流中的哪些键是彼此重复的。我确信我可以使用旧的Java集合API来实现 hard way ,但在此解决方案中,效率和利用Java 8 API对我来说非常重要。
答案 0 :(得分:1)
如果没有太多使用Java 8的功能习惯用法,我只需使用Set#retainAll进行每次比较(总共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
}
}
答案 1 :(得分:0)
您要做的第一件事就是将所有密钥收集到一个流中:
Stream<String> keys = Stream.of(
fizzes.keySet().stream(),
buzzes.keySet().stream(),
foobars.keySet().stream())
.flatMap(s -> s);
现在你可以collect
将它们变成计数图:
Map<String, Long> counts = keys.collect(
Collectors.groupingBy(Function.identity(),
Collectors.counting()));
您可以使用计数&gt;过滤条目1:
Set<String> duplicates = counts.entrySet().stream()
.filter( e -> e.getValue() > 0)
.map(Entry::getKey)
.collect(Collectors.toSet());
如果此设置不为空,则抛出异常。