General map with lists of comparable

I want Map

multiple lists, each of which consists of objects Comparable

, but not always the same, so it can be List

Doubles

and List

of Strings

, etc.

Map<String, List<Comparable<?>>>

Unfortunately, Map

as defined above will not be useful as the elements in each List

cannot be compared. So I had to cheat and inject a type class into a class:

class MyClass<T extends Comparable<? super T>> {
    Map<String, List<T>> myMap;
}

      

This is not entirely correct, because not all lists are of the same type. But it works, the only thing I need to do is make the cast type to T

when I add Double

to the doubles list or String

to the string list. I'm sure each type is only added to lists of the correct type.

Is there a better way to solve this problem?

An alternative is availability Map

for each type List

. But this will just make the code uglier and the only thing I do with the lists is sort them and insert them into the DB as String values, so I only call toString

in mappings.

+3


source to share


3 answers


You can use List<Object>

to make it general and for this purpose.
You might want to do checks instance of

for some data types within the list.

Map<String, List<Object>> map = new HashMap<>();

List<Object> list;

list = new ArrayList<>(Arrays.asList(new Object[] { 1, 2, 3.45, "dev", 'A', true, false }));
map.put("key1", list);

list = new ArrayList<>(Arrays.asList(new Object[] { false, 100, 5.1234f, "user", 'Z', true }));
map.put("key2", list);

for (Map.Entry<String, List<Object>> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " => " + entry.getValue());
}

      



Output:
key1 => [1, 2, 3.45, dev, A, true, false] key2 => [false, 100, 5.1234, user, Z, true]

+1


source


From the docs java generic wildcard it says:

In general code, a question mark (?), Called a wildcard, represents an unknown type .

And:

The wildcard is never used as a type argument for a general method invocation, instantiation of a generic class, or supertype.

So, if you have the following declaration:

List<?> list = new ArrayList<>();

      

Then you can't add anything to list

, because you just told the compiler that "I don't know the type of objects that will be placed in list

"



So your code List<Comparable<?>>

means "I want the list to contain comparable objects, but I don't know the type", which is not good for the compiler, because the compiler really needs to know the type information for it to work.

The list of uses includes any objects Comparable

, you can use the upper bounded wildcards , for example:

Map<String, List<? extends Comparable>> map = new HashMap<>();

      

Then it will be convenient for you to put any Comparable

list as the value for this card:

public static void main(String[] args) {
    Map<String, List<? extends Comparable>> map = new HashMap<>();
    List<Integer> as = new ArrayList<>();
    as.add(1);
    as.add(5);
    as.add(3);

    map.put("as", as);

    List<String> bs = new ArrayList<>();
    bs.add("hello");
    bs.add("world");
    bs.add("generics");

    map.put("bs", bs);
}

      

Finally, I think you will be interested in inheritance and subtyping in generics , hope this might be helpful to you.

0


source


It looks a bit like a heterogeneous map. What are you actually going to do with a list of comparable data, other than comparing with it?

However, if you want the lists to be of different types, then the indirect has to be around List

.

public final class SortableList<T extends Comparable<? super T>> {
    private final List<T> elements;
    public SortableList(List<T> elements) {
        this.elements = elements;
    }
    public List<T> elements() {
        return elements;
    }
}

...

Map<String,SortableList<?>> sortables;
...
Comparable<?> colaMax = Collections.max(sortables.get("shirley").elements());

      

0


source







All Articles