Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast from List<T> in Map entry value to Set<T>

Tags:

java

generics

I have a Map<String,Object> with an entry that contains a value of List<String>. I need to get the contents of the List<String> into a Set<String>. I am using the following code:

Map<String, Object> map = SomeObj.getMap();
if (map.get("someKey") instance of List<?>) {

    Set<String> set = new HashSet<String>((List<String>) map.get("someKey"));
}

My Eclipse-based IDE has a couple of warnings on this line:

  • Type safety: Unchecked cast from Object to List

The code compiled and runs as it is intended to. Is there a better way to do this though? Annotating the line with @SuppressWarnings("unchecked") is my last and least preferred option.

like image 262
Web User Avatar asked Jan 03 '23 12:01

Web User


2 Answers

You can do the following:

Map<String, Object> map = SomeObj.getMap();
String key = "someKey";
if (map.get(key) instanceof List<?>) {
    List<?> list = (List<?>) map.get(key);
    Set<String> set = new HashSet<>();
    // Cast and add each element individually
    for (Object o : list) {
        set.add((String) o);
    }
    // Or, using streams
    Set<String> set2 = list.stream().map(o -> (String) o).collect(Collectors.toSet());
}
like image 143
k_ssb Avatar answered Jan 13 '23 11:01

k_ssb


String is peculiar, in that a method exists on all objects to convert to it, namely Object.toString(). Invoking toString() on a String returns itself.

So, if you know it's a List<?>, you can convert to a Set<String> as follows:

List<?> list = (List<?>) map.get("some key");
Set<?> set = list.stream().map(Object::toString).collect(Collectors.toSet());

(You may need to handle null elements)

like image 41
Andy Turner Avatar answered Jan 13 '23 11:01

Andy Turner