0

Im working on creating app to read lyrics from textfiles. Is there any way to minimize this code because the switch case can reach hundreds?

    int itemPosition=position;
    itemName=song[position];
    Intent openViewLyric=new Intent(this, ViewLyric.class);

    switch(itemPosition)
    {
        case 0:
            openViewLyric.putExtra("song", itemName);
            openViewLyric.putExtra("resid", R.raw.above_all);
            startActivity(openViewLyric);
            break;

        case 1:
            openViewLyric.putExtra("song", itemName);
            openViewLyric.putExtra("resid", R.raw.age_to_age);
            startActivity(openViewLyric);
            break;

        case 2:
            openViewLyric.putExtra("song", itemName);
            openViewLyric.putExtra("resid", R.raw.as_the_deer);
            startActivity(openViewLyric);
            break;
Tuss
  • 865
  • 1
  • 8
  • 12
  • 2
    The only thing that appears to be changing is the R.raw extra. Can you create an array of all these and just use the position to get the resource. eg putExtra("resid",myRawArray[position]); – Revive Aug 21 '14 at 15:05
  • write a function that does that so it will minimize the repitition of code – rush2sk8 Aug 21 '14 at 15:08

4 Answers4

3

Your cases repeat the same code with different data.

You could instead pull the data from a Map, and write that code once. A map works even with a sparse array. A primitive array can be used if the array is known to be fairly full.

For example, if R.raw were an enum class, then you could initialize it once:

 private static Map<Integer,R.raw> s_mapPositionToData 
     = new HashMap<Integer,R.raw>();
 static {
     // Fill the map
 }

And then use it instead of the switch in your code above:

 int itemPosition=position;
 itemName=song[position];
 R.raw itemRaw s_mapPositionToData.get( position );
 Intent openViewLyric=new Intent(this, ViewLyric.class);

 openViewLyric.putExtra("song", itemName);
 openViewLyric.putExtra("resid", itemRaw );
 startActivity(openViewLyric);

You could put the itemName in the same map, with the help of a containing type. For example, you could declare a type ExtraSongData including both the name and an R.raw, then declare the map to be Map<Integer,ExtraSongData>.

Andy Thomas
  • 78,842
  • 10
  • 93
  • 142
  • Thank you so much.. I learned Java from this book, JavaTm Programming by Joyce Farrell but this book never mention about map, sparse array. Is there any book you suggest me to read? Regards – Tuss Aug 22 '14 at 01:57
  • @Tuss - It would be helpful to learn about data structures in general, data structures in Java, and good practices in Java. For data structures, I personally like Sedgewick's *Algorithms* and Cormen et al.'s *Introduction to Algorithms*. For data structures in Java, see http://docs.oracle.com/javase/tutorial/collections/. The book *Core Java 1* also includes a section on collections, among other concepts you'll need to understand. For good practices, please obtain and read Bloch's *Effective Java.* – Andy Thomas Aug 22 '14 at 15:00
  • @Tuss - Also, welcome to StackOverflow. If you find an answer (or question) useful, you can click the up-arrow to the left. If you consider this the best answer, you can click the checkbox to the left. – Andy Thomas Aug 22 '14 at 15:01
3

Initialize an R array early on (assuming R is the type of R.raw.above_all, etc), mapping position in the array to specific R values.

R[] allRs = new R[] {
    R.raw.above_all,
    R.raw.age_to_age,
    R.raw.as_the_deer
};

Then you can replace your entire switch statement with:

openViewLyric.putExtra("song", itemName);
openViewLyric.putExtra("resid", allRs[itemPosition]);
startActivity(openViewLyric);
psicopoo
  • 1,296
  • 1
  • 10
  • 20
1

Create a lookup list:

private static List<Object> resids = new ArrayList<Object>(){{
  add(R.raw.above_all);
  add(R.raw.age_to_age);
  .
  .
  .
}}

When you need to use it you can just call

 openViewLyric.putExtra("song", itemName);
 openViewLyric.putExtra("resid", resids.get(itemPosition));
 startActivity(openViewLyric);

EDIT

It seems that your only choice is which collection you should use. As I chose the list as first I'm going to support the list based on the fact that is definitively more maintainable than an array and that a Map structure is too much for your purpose (assuming that itemPosition is ALWAYS less or equal of the List size).

Community
  • 1
  • 1
Narmer
  • 1,386
  • 6
  • 16
0

Why not to fill a map with all the values. This can be done in the constructor, onCreate method or even in static method:

Map<Integer, Integer> songsMapping = new HashMap<Integer, Integer>();
songsMapping.put(0, R.raw.above_all);
songsMapping.put(1, R.raw.age_to_age);
songsMapping.put(2, R.raw.as_the_deer);

Please notice that songsMapping has to be a field so to be initialized just once

And then your code will change to something like that:

int itemPosition=position;
Intent openViewLyric=new Intent(this, ViewLyric.class);
openViewLyric.putExtra("song", song[position]);
openViewLyric.putExtra("resid", songsMapping.get(itemPosition));
startActivity(openViewLyric);

Kind Regards