繁体   English   中英

寻找使用流生成地图的更好方法

[英]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建议的那样,您还可以使用collectingAndThenCollections.unmodifiableMaptoMap的结果创建一个不可修改的地图:

.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM