我的要求:我有一个接口(interface),该接口(interface)应仅包含诸如 public final static short SOME_CONST = whatever
之类的条目。问题:短常量需要唯一。当存在重复项时,我主要对 SOME_CONST_A、SOME_CONST_B、... 名称引起冲突感兴趣。
我写了下面的测试来通过反射来测试它。它有效,但我发现它笨重且不太优雅:
@Test
public void testIdsAreUnique() {
Map<Short, List<String>> fieldNamesById = new LinkedHashMap<>();
Arrays.stream(InterfaceWithIds.class.getDeclaredFields())
.filter(f -> f.getClass().equals(Short.class))
.forEach((f) -> {
Short key = null;
String name = null;
try {
key = f.getShort(null);
name = f.getName();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
fieldNamesById.computeIfAbsent(key, x -> new ArrayList<>()).add(name);
});
assertThat(fieldNamesById.entrySet().stream().filter(e -> e.getValue().size() > 1)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)), is(Collections.emptyMap()));
}
有没有办法避免中间本地 map 实例?
(奖金问题:有没有更好的方法来缩短用键/值对填充映射的 lambda?)
最佳答案
这是一个按静态值对字段进行分组的流。注意关于其他更改/更正的一些评论
Map<Short, List<String>> fieldNamesById =
Arrays.stream(InterfaceWithIds.class.getDeclaredFields())
//using short.class, not Short.class
.filter(f -> f.getType().equals(short.class))
//group by value, mapping fields to their names in a list
.collect(Collectors.groupingBy(f -> getValue(f),
Collectors.mapping(Field::getName, Collectors.toList())));
调用读取值的方法如下(主要是为了避免流中的 try/catch block ):
private static Short getValue(Field f) {
try {
return f.getShort(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
关于java - 如何从流计算 map ,然后检查 map 值的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52406429/