简体   繁体   中英

If condition is true even then else is executing

I have an enum defined as below, which contains a static function fromString(String s) which is like valueOf(String s) but case insensitive.

enum Platform {
    TWITTER("TWITTER"), INSTAGRAM("INSTAGRAM"), UNKNOWN;

    private String value;

    Platform(String value) {
        this.value = value;
    }

    private static final Map<String, Platform> stringToEnumMap = new HashMap<>();

    static {
        for (Platform platform : values()) {
            stringToEnumMap.put(platform.toString().toLowerCase(), platform);
        }
    }

    public static Platform fromString(String symbol) {
        Platform platform = stringToEnumMap.get(symbol.toLowerCase());
        if (platform != null) {
            return platform;
        } else {
            return UNKNOWN;
        }
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return getValue();
    }

}

but when I execute the following code

Platform platform = Platform.fromString("twitter");

I get Platform.UNKNOWN returned on few devices on production.

Any Idea?

Update

symbol.toString() gives twitter

stringToEnumMap.toString() gives this

Platform StringToEnumMap: { twıtter=TWITTER, ınstagram=INSTAGRAM, unknown=UNKNOWN}

If you look closely, the letter i is different in the keys of HashMap and thats why string comparison fails.

the hexvalue of letter ı in stringToEnumMap is 0131, whereas the it should be 0069

Why is this happening on only few devices? How to avoid it?

It seems to be a dirty ide issue, try to clean up your project, build and run again.

UPDATE Try replacing your if statement by getOrDefault method:

public static Letter fromString(String symbol) {
    return stringToEnumMap.getOrDefault(symbol.toLowerCase(), UNKNOWN);
}

In my Opinion, there is no need for a map.... nor a new method for doing something that valueOf() is able to do...

look this implemetation..

enum ECase {
    A, B, UNK;

    public static ECase resolveEnumFromString(final String string) {
        ECase r = null;
        try {
            r = ECase.valueOf(string.toUpperCase());
        } catch (final IllegalArgumentException e) {
            r = ECase.UNK;
        }
        return r;
    }
}

you can verify the results doing:

    ECase d = null;
    d = ECase.resolveEnumFromString("a");
    System.out.println(d);
    d = ECase.resolveEnumFromString("A");
    System.out.println(d);
    d = ECase.resolveEnumFromString("0");
    System.out.println(d);

I am able to find what the issue was. After some careful logging I found the issue was this http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug .

Apparently toLowerCase() and toUpperCase() functions are locale dependent due to which you can't use them safely for case insensitive string comparison. So all you need to do is pass the english locale in the parameter of these functions like this -

toLowerCase(Locale.ENGLISH) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM