¿Alternativa a la declaración de cambio, cuando se conocen todos los casos posibles?

Im quite new to Java and i have stumbled upon the following problem.

Im reading a list of movies from a txt file, one of the fields is a string representation of what genre(s) the movie is classified as, aswell as a numerical representation of 1-5 signifying that the movie has recieved one or more awards.

eks. one movie could have the following value in this field "12bSt" this would signify that the movie is a b = biographical, S = sports, 2 = won an academy award. atm i do this:

    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 & sound";       break;
            case 5:genreArr[i] = "AFI top 100";     break;
        }
    }
    return genreArr;
}

my question is, what implementation would be more effective than this?

preguntado el 08 de noviembre de 11 a las 19:11

Hahah I want to steal that pic >_< -

At first glance it looks like your code will work. What's the problem? -

@GregHewgill im looking for a more effective way to solve this, as there are some 20k movie entries that will run through this and other methods. -

5 Respuestas

Create a Map (once), and look up the values (still looping through your char array).

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

p.s. Be aware that you have a bug in your current code. case 2: debiera ser case '2':.

respondido 08 nov., 11:23

Use a map with the character (or just a string) as the key, the string as the value.

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

Essentially the same thing could be done with enums, and if you need to pass around that info, it might be better to do it in a typesafe way.

respondido 09 nov., 11:00

but the OP asked for something more effective, not for smaller code... Are you sure that the boxing of the tanque a Caracter (or the creation of a Cordón) más el HashMap lookup is going to be faster than a lookupswitch or a tableswitch? (note that I don't think the OP really needs "faster code", I just point out that I'm not sure boxing+map lookup is faster than a tableswitch or lookupswitch) - TacticalCoder

@user988052 That's "efficient", not "effective", although I did mix up my implementations. I took it to mean from a code maintenance, appearance, and readability standpoints. - Dave Newton

ah ah :) OP wrote: "my question is, what implementation would be more effective than this?" and then he commented again: "im looking for a more effective way to solve this, as there are some 20k movie entries". OP used twice the word "effective" and implied he was after performance (mentionning there were 20K entries, as if that was a lot). I should have used [sic] after "effective" to show it was the OP's usage of the word, not mine. That said I agree that what you wrote is more readable and I doubt that the OP would have any speed issues with a mere 20K movies :) - TacticalCoder

You can initially put them all in a HashMap, and then simply access it. Do this if you'll need more accesses to this mapping. If you're just gonna check this once, you can let it like this (I'd suggest you to put it in a method).

respondido 08 nov., 11:23

it is a method, but wrong indentation^^ String[] genreStringToArray(String genre){ - Jeger

I think it is best to use object oriented programming in this instance, that is create an object that represents what you are trying to do. Here is an example, without knowing your domain.

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  
} 

Now you can store each of these objects into whatever structure you would like. Now if you push these values into a Map or a List you can benefit from the fast lookup times of either of these structures.

respondido 09 nov., 11:00

I would use a database table for this.

respondido 09 nov., 11:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.