Альтернатива инструкции switch, когда известны все возможные случаи?

#java #switch-statement

#java #switch-statement

Вопрос:

Я совсем новичок в Java, и я наткнулся на следующую проблему.

Я читаю список фильмов из текстового файла, одно из полей представляет собой строковое представление того, к какому жанру (ам) относится фильм, а также числовое представление 1-5, означающее, что фильм получил одну или несколько наград.

экс. один фильм может иметь следующее значение в этом поле «12bSt», это означало бы, что фильм является b = биографическим, S = спортивным, 2 = получил премию Оскар. когда я делаю это:

     String[] genreStringToArray(String genre) {
    char[] genreCharArray = genre.toCharArray(); 
    this.genreArr = new String[genreCharArray.length];
    for (int i = 0; i < genreCharArray.length; i  ) {
        switch (genreCharArray[i]) {
            case 'a': genreArr[i] = "Action";       break;
            case 'A': genreArr[i] = "Animation";        break;
            case 'b': genreArr[i] = "biographical";     break;
            case 'c': genreArr[i] = "comedy";       break;
            case 'C': genreArr[i] = "children";     break;
            case 'd': genreArr[i] = "drama";        break;
            case 'D': genreArr[i] = "documentary";      break;
            case 'e': genreArr[i] = "epic";         break;
                                 ..... etc
            case 2:genreArr[i] = "Academy award";       break;
            case 3:genreArr[i] = "Palme d`or";      break;
            case 4:genreArr[i] = "Sight amp; sound";       break;
            case 5:genreArr[i] = "AFI top 100";     break;
        }
    }
    return genreArr;
}
  

мой вопрос в том, какая реализация была бы более эффективной, чем эта?

Комментарии:

1. Хахах, я хочу украсть эту картинку >_<

2. На первый взгляд кажется, что ваш код будет работать. В чем проблема?

3. @GregHewgill я ищу более эффективный способ решить эту проблему, поскольку существует около 20 тысяч записей фильма, которые будут выполняться с помощью этого и других методов.

Ответ №1:

Создайте карту (один раз) и найдите значения (все еще просматривая ваш массив символов).

 Map<Character, String> map= new HashMap<Character, String>();
....
    genreArr[i] = map.get(genreCharArray[i]);
....
  

p.s. Имейте в виду, что у вас есть ошибка в вашем текущем коде. case 2: должно быть case '2': .

Ответ №2:

Используйте сопоставление с символом (или просто строкой) в качестве ключа, строка — в качестве значения.

 Map<Character, String> genres = new HashMap<Character, String>() {{
    put('b', "biographical");
    put('C', "Children");
    put('2', "Academy Award");
    // etc...
}};

String genre = "b2C";

List<String> info = new ArrayList<String>();
for (int i = 0; i < genre.length(); i  ) {
    info.add(genres.get(genre.charAt(i));
}

System.out.println(StringUtils.join(info, ", "));

Outputs: biographical, Academy Award, Children
  

По сути, то же самое можно было бы сделать с enum s, и если вам нужно передать эту информацию, возможно, было бы лучше сделать это типобезопасным способом.

Комментарии:

1. но OP запросил что-то более эффективное, а не для кода меньшего размера… Вы уверены, что преобразование символа в Character (или создание строки ) плюс поиск по хэш-карте будет быстрее, чем lookupswitch или tableswitch? (обратите внимание, что я не думаю, что OP действительно нуждается в «более быстром коде», я просто указываю, что я не уверен, что boxing map lookup быстрее, чем tableswitch или lookupswitch)

2. @user988052 Это «эффективно», а не «действенно», хотя я перепутал свои реализации. Я понял, что это означает с точки зрения обслуживания кода, внешнего вида и удобочитаемости.

3. ах, ах 🙂 OP написал: «мой вопрос в том, какая реализация была бы более эффективной, чем эта?» и затем он снова прокомментировал: «я ищу более эффективный способ решить это, поскольку существует около 20 тысяч записей фильма» . OP дважды использовал слово «эффективный» и подразумевал, что он был заинтересован в производительности (упоминая, что было 20 тысяч записей, как будто это было много). Я должен был использовать [sic] после «effective», чтобы показать, что это было использование слова OP, а не мое. Тем не менее, я согласен с тем, что то, что вы написали, более читаемо, и я сомневаюсь, что у OP будут какие-либо проблемы со скоростью при просмотре всего 20 Тыс. фильмов 🙂

Ответ №3:

Вы можете изначально поместить их все в HashMap, а затем просто получить к нему доступ. Сделайте это, если вам потребуется больше обращений к этому отображению. Если вы просто собираетесь проверить это один раз, вы можете оставить это так (я бы посоветовал вам поместить это в метод).

Комментарии:

1. это метод, но с неправильным отступом ^^ String[] genreStringToArray(жанр строки){

Ответ №4:

Я думаю, что в данном случае лучше всего использовать объектно-ориентированное программирование, то есть создать объект, который представляет то, что вы пытаетесь сделать. Вот пример, без знания вашего домена.

 public class Film
{  
   private  Genre genre; //Make this a List if necessary 
   private Award award;  // Make this a List if necessary    
   //Other things that define a Film
}  

public class Genre  
{  
   enum GenreDefinition  
   {  
       ACTION("Action")  //Add more as necessary  
   }  
   //Other things that define a genre  
}  

public class Award  
{  
    enum AwardTypes  
    {  
      OSCAR("Oscar")  //Add more as necessary  
     }  
     //Other things that define an award  
} 
  

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

Ответ №5:

Я бы использовал для этого таблицу базы данных.