Search code examples
javaguava

Mapping enum values by its name


I am trying to map all the values ​​of this enum by its componentType. unfortunately I don't know how to map it with the array, tried using toImmutableMap (v-> v.componentType, v-> v) but this only work with a ImmutableMap<String, MatchType> and i need map it as array (MatchType[]), can someone tell me how i can do that or if there is a better way?

ImmutableMap<String, MatchType[]> findByComponentType = Arrays.stream(MatchType.values()).collect(toImmutableMap(v -> /** what to put here */));

Example: If i use findByComponentType.get("android.support.v4.app.Fragment") it should return SUPPORT_FRAGMENT & SUPPORT_FRAGMENT_PRE_API23.

 private enum MatchType {
  ACTIVITY(
      "android.app.Activity",
      "onCreate",
  FRAMEWORK_FRAGMENT(
      "android.app.Fragment",
      "onAttach",
  FRAMEWORK_FRAGMENT_PRE_API23(
      "android.app.Fragment",
      "onAttach",,
  SUPPORT_FRAGMENT(
      "android.support.v4.app.Fragment",
      "onAttach",
  SUPPORT_FRAGMENT_PRE_API23(
      "android.support.v4.app.Fragment",
      "onAttach");

  MatchType(String componentType, String lifecycleMethod) 

Solution

  • Instead of ImmutableMap<String, MatchType[]> you really want ImmutableMultimap (ImmutableSetMultimap specifically because your values would be enum value suitable for set instead of array/list).

    Create your reverse mapping like this:

    private static final ImmutableSetMultimap<String, MatchType> COMPONENT_TYPE_LOOKUP =
            EnumSet.allOf(MatchType.class).stream()
                    .collect(toImmutableSetMultimap(
                            matchType -> matchType.componentType, // or MatchType::getComponentType if there's a getter,
                            matchType -> matchType                // or Function.identity()
                    ));
    

    And then you'd have

    static Set<MatchType> findByComponentType(String componentType) {
        return COMPONENT_TYPE_LOOKUP.get(componentType);
    }
    

    and in the end it'll return a set of matching types:

    @Test
    public void shouldMatchType() {
        final Set<MatchType> types = findByComponentType("android.support.v4.app.Fragment");
        assertThat(types)
                .containsExactlyInAnyOrder(MatchType.SUPPORT_FRAGMENT,
                                           MatchType.SUPPORT_FRAGMENT_PRE_API23);