Создание поиска по перечислению.Несколько ключей для одного объекта - PullRequest
0 голосов
/ 26 июня 2018

Я использовал превосходный шаблон Джошуа Блоха для создания поисков от строк (или других типов) до объектов перечисления. После создания объектов перечисления нам нужно создать карту как:

private static final Map<String, MyEnumType> MY_MAP =
    Stream.of(values())
          .collect(toMap(MyEnumType::myFunction, e -> e));

где myFunction возвращает строку, которую я хочу отобразить. Затем мы создаем статический метод, который использует карту для поиска объектов по ключу.

Это хорошо работает, но теперь у меня есть требование отобразить каждый объект перечисления из нескольких строк.

Я обновил myFunction для возврата List<String>. Теперь я хочу, чтобы мой поток перебирал список, вставляя в карту объекты e, но я не могу понять, как именно.

Мне кажется, проблема в том, что если я создаю поток, я теряю объект e для вставки.

Обновление: Похоже, есть некоторая путаница в отношении того, что я прошу сделать. У меня есть два рабочих ответа (поэтому я счастлив), но я добавлю пример, который может помочь любому, кто хочет решить ту же проблему.

Рассмотрим перечисление дней недели - тип должен содержать ровно 7 объектов. Я пытаюсь написать метод поиска из текстового описания. Объект TUESDAY должен отображаться с двух разных ключей - tuesday и tue. Метод myFunction вернет оба этих ключа в список

Для целей поиска мне нужно, чтобы у моего Map<String, Week> было два ключа, указывающих на объект TUESDAY.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Поскольку ваш заголовок гласит Несколько ключей к одному объекту Я бы предположил, что вы хотите отобразить каждый объект из Списка на один и тот же элемент перечисления, например, иметь несколько способов его получить

Он будет перебирать перечисление, и для каждого из них будет List<Strings> и создаст Entry (ключ / значение), и они свяжут их для построения карты

Я добавляю базовое перечисление для демонстрации, где myFunction возвращает имя перечисления в нижнем и верхнем регистре

 enum AirplaneBrand{    
    AIRBUS(Arrays.asList("A380","A330")),
    BOEING(Arrays.asList("787","737"));       

    private List<String> values;    
    AirplaneBrand(List<String> values){ this.values = values; }    
    public List<String> myFunction(){  return values; }        
  }

    public static void main(String[] args){
        final Map<String, AirplaneBrand> MY_MAP =  
            Stream.of(AirplaneBrand.values())
                  .flatMap(en -> en.myFunction().stream().map(elt -> new AbstractMap.SimpleEntry<String,AirplaneBrand>(elt, en)))
                  .collect(toMap(Entry::getKey, Entry::getValue));

       System.out.println(MY_MAP);                 // {A330=AIRBUS, A380=AIRBUS, 787=BOEING, 737=BOEING}
        System.out.println(MY_MAP.get("737"));     // BOEING
        System.out.println(MY_MAP.get("A380"));    // AIRBUS
    }
}
0 голосов
/ 26 июня 2018

Я бы порекомендовал взять дополнительную строку

private static final Map<String, MyEnumType> MY_MAP;

static {
    Map<String, MyEnumType> local = new HashMap<>();
    EnumSet.allOf(MyEnumType.class).forEach(e -> e.getValues().forEach(s -> local.put(s, e)));
    MY_MAP = Collections.unmodifiableMap(local);
}

, что приводит к

public enum MyEnumType {

    RED(List.of("red", "dark red")),
    BLUE(List.of("blue", "light blue", "dark blue"));

    private List<String> values;

    MyEnumType(List<String> values)
    {
        this.values = values;
    }

    public List<String> getValues()
    {
        return values;
    }
} 

к отображению

red -> RED
blue -> BLUE
light blue -> BLUE
dark red -> RED
dark blue -> BLUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...