[英]Find a better way to generate a map using streams
我有这个枚举:
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方法的第二个参数放在一个新方法中,但是我认为我只是将复杂性移到了其他地方。
您是否有关于如何以简单方式实现同一目标的建议?
您可以在进行平面映射时将其放入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));
稍微简单一点:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.