开发者

How do I reduce my code using a function when using a lot of references like PIXELS_PER_INCH = 72?

I have some code that needs reducing and it was recommended to me on Reddit.com that I use functions to do it. But the problem is the code is mostly a collection of public static final "references" such as PIXELS_PER_INCH = 72.

I open sourced my app on GitHub, if anyone wants to look at it that way.

Here's an example of where I assign values to my constants:

public static final int PICTURES_4 = 0;
public static final int PICTURES_6 = 1;
public static final int PICTURES_8 = 2;
public static final int PICTURES_10 = 3;
public static final int PICTURES_12 = 4;

public static final int PICTURES_OPTION_0 = 4;
public static final int PICTURES_OPTION_1 = 6;
public static final int PICTURES_OPTION_2 = 8;
public static final int PICTURES_OPTION_3 = 10;

And here's an example of where I use those constant references:

switch (settings.getInt(SettingsActivity.PICTU开发者_开发技巧RES_OPTION, SettingsActivity.DEFAULT_PICTURES_OPTION)) {
        case SettingsActivity.PICTURES_4:
            totalImages = SettingsActivity.PICTURES_OPTION_0;
            break;
        case SettingsActivity.PICTURES_6:
            totalImages = SettingsActivity.PICTURES_OPTION_1;
            break;
        case SettingsActivity.PICTURES_8:
            totalImages = SettingsActivity.PICTURES_OPTION_2;
            break;

Essentially, I would like to know how to use a function to reduce the code but still keep the ability to use readable references. Or is my idea of using a readable reference wrong? I learned in an online programming class about using constants as readable references (such as PIXELS_PER_INCH = 72) instead of using absolute values.

Thank you for your time.

Update: I ended up using aioobe and Lloyd Ozymandias Force's suggestions. I used EnumMap in a for loop. Within the for loop, though, I couldn't use myEnumMap.values() for some reason. I Googled it and found a different way to do it using myEnumMap.class.getEnumConstants(), instead.


  • You can put the options in a map, and do get(option) instead of switch(option)

    Initialize the map like this:

    Map<Integer, Integer> optionsMap = new HashMap<Integer, Integer>() {{
        put(SettingsActivity.PICTURES_4, SettingsActivity.PICTURES_OPTION_0);
        put(SettingsActivity.PICTURES_6, SettingsActivity.PICTURES_OPTION_1);
        ...
    }};
    

    and then replace the switch like this:

    totalImages = optionsMap.get(settings.getInt(SettingsActivity.PICTURES_OPTION,
                                       SettingsActivity.DEFAULT_PICTURES_OPTION));
    
  • Or, (since you seem to have a simple integer to integer mapping) you could put your values in a lookup table.

  • Or, you can put it in a function and replace all breaks with returns:

    public int getPictureOption() {
        switch (settings.getInt(SettingsActivity.PICTURES_OPTION,
                                SettingsActivity.DEFAULT_PICTURES_OPTION)) {
                case SettingsActivity.PICTURES_4:
                    return SettingsActivity.PICTURES_OPTION_0;
    
                case SettingsActivity.PICTURES_6:
                    return SettingsActivity.PICTURES_OPTION_1;
    
                case SettingsActivity.PICTURES_8:
                    return SettingsActivity.PICTURES_OPTION_2;
        }
    }
    

    and then do

    totalImages = getPictureOption();
    

If you consider your constants to be self explanatory, you could get rid of all SettingsActivity. by adding a static import in the top of your file:

import static your.package.SettingsActivity.*;


Do not switch on enum values - this is a job for polymorphism or a Map / look up table as mentioned by aiobe.

To illustrate one technique for working with enums in Java, consider the following SettingsActivity enum with a polymorphic getPictureOption() method. It is declared abstract in the enum body, forcing each enum constant to implement that method. This technique is described in more detail in Effective Java 2nd Edition (Josh Bloch).

enum SettingsActivity {
    OPTION_1(){
        public int getPicureOption() {
            return  myValue * 6;
        }
    },
    OPTION_2(){
        public int getPictureOption() {
            return Math.pow(myValue,5);
        }
    },
    ...
    OPTION_N() {
        public int getPictureOption() {
            return myValue-6;
        }
    };

    private final int myValue;

    private SettingsActivity(int myValue) {
        this.myValue = myValue;
    }

    // enums can have abstract methods!
    public abstract int getPictureOption();
}

SettingsActivity foo = getSettingsActivityFromSomewhere();

// polymorphic getPictureOption method - we don't
// know which activity was clicked
int something = foo.getPictureOption();

Of course, this is just sample code to illustrate the kind of thing you can do. I'm not sure what the intent of your switch statement is or where the SettingsActivity enum comes from so I can't really offer more guidance.

In case you want to use a Map, the EnumMap class provided by the JDK provides an ultra efficient Map implementation for enums (it's implemented as a single long value for enums with fewer than 65 constants and an array of long values for > 64 constants). Either way, the look up operations are O(1) (as opposed to O(lg n) for a hash map).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜