简体   繁体   中英

Mapping a set of strings to a specific key value

Say I have 3 sets of string values:

fruit: apple, berry, banana

color: red, blue, orange

vehicle: car, plane, truck

I'm looking for the most efficient way with Java to retrieve the parent value for each set such as:

getParentValue("banana") ---> fruit

Solution 1:

create a bunch of if/else statements or switch case:

if (fruitSet.contains(elem)) {
   return "fruit";
}
else if (colorSet.contains(elem)) {
   return "color";
} ...

This yields an O(n) lookup, n being numbers of sets.

Solution 2:

Create a hashmap which stores every child to parent value,

Key/Value:

apple/fruit
berry/fruit
banana/fruit
red/color
blue/color
orange/color
...

This yields an O(1) lookup time, but generates a large hash map as it stores every key - for some reason this solution feels ugly.

I am looking for some opinions or other approaches which might be more elegant.

Here is some code that only has 3 entries in the Map.

public static void main(String[] args) {
    Map<String, List<String>> myMap = new HashMap<>();
    myMap.put("fruit", new ArrayList<String>(Arrays.asList("apple","berry","banana")));
    myMap.put("color", new ArrayList<String>(Arrays.asList("red","blue","orange")));
    myMap.put("vehicle", new ArrayList<String>(Arrays.asList("car","plane","truck")));
    System.out.println(getKey(myMap, "blue"));
}

public static String getKey(Map<String, List<String>> map, String value) {
    for (String key : (Set<String>)map.keySet()) {
        List<String> list = map.get(key);
        if (list.contains(value)) {
            return key;
        }
    }
    return null;
}

The best approach is definitely your solution #2: if you want to be able to look up the category given a member, then the most efficient way is to have a Map from the member to the category. That's exactly what Map is for.

(Note that regardless of your approach, you'll have to store all the members. Storing them as keys is no uglier than storing them in some less-efficient way.)

Hashmap idea is quite good but if you wanna further improve, you can set each object to an integer and store it in an array. This would be nice if you have some categories with very long name.

For example,

something1/very very long string
something2/very very long string

After the conversion:

apple/0
berry/0
banana/0
red/1
blue/1
orange/1
...
something1/i
something2/i

And your array will be:

arr = {"fruit", "color", ....., "very very long string", ....};

Unless you have so many entries( tens or millions) in your list with very long strings categories, it won't worth.

For example, your average string size is 16 chars and you have a million different rows, it means only 16 MB which is nothing for a modern computer, and you save only 12MB as an integer is 4B.

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