我有这个枚举:
public enum FieldType
{
INTEGER
{
@Override
Set<Class<?>> getTypes()
{
return new HashSet<>(Arrays.asList(int.class, Integer.class));
}
},
LONG
{
@Override
Set<Class<?>> getTypes()
{
return new HashSet<>(Arrays.asList(long.class, Long.class));
}
};
// More types...
private static final Map<Class<?>, FieldType> _fieldTypes;
static
{
_fieldTypes = Stream.of(values()).
flatMap(ft -> ft.getTypes().stream()).
collect(toMap(t -> t,
t -> Stream.of(values()).
filter(ft -> ft.getTypes().contains(t)).
findAny().
get()
));
}
abstract Set<Class<?>> getTypes();
// More methods...
}
正如您所看到的,我在此枚举中有一个映射,它将类型映射到字段类型。我设法使用流在静态块中填充此映射。它有效,但我认为这可能是一种更好,更简洁的方法。我可以将 toMap 方法的第二个参数放在一个新方法中,但我认为我只是将复杂性转移到其他地方。
您是否有关于如何以简单方式实现同样目标的建议?
答案 0 :(得分:3)
您可以在展平时插入Entry
:
_fieldTypes = Stream.of(values())
.flatMap(ft -> ft.getTypes().stream() // for every Class<?> of a FieldType...
.map(cls -> new SimpleEntry<>(cls, ft))) // get Entry<Class<?>, FieldType>
.collect(toMap(Entry::getKey, Entry::getValue));
正如bradimus建议的那样,您还可以使用collectingAndThen
和Collections.unmodifiableMap
根据toMap
的结果创建不可修改的地图:
.collect(collectingAndThen(toMap(Entry::getKey, Entry::getValue),
Collections::unmodifiableMap));
答案 1 :(得分:1)
稍微简单一点:
Map<Class<?>, FieldType> map = Arrays.stream(FieldType.values())
.flatMap(ft -> ft.getTypes().stream()
.map(cl -> new AbstractMap.SimpleEntry<>(cl, ft)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
显然你可以把它包装成Collections.unmodifiableMap