Verschillende soorten collections toevoegen aan een HashMap

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Megabytes
  • Registratie: Oktober 2021
  • Laatst online: 14-03-2022
Mijn vraag
Is het mogelijk om verschillende soorten collecties (HashSet, ArrayList, LinkedList, TreeSet) toe te voegen aan een HashMap als value?

Wat ik probeer, maar wat niet werkt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public enum CollectionType {
    ArrayList, HashSet, Undefined
}

public enum MyEnum {
    One, Two, Three, Four
}

public class myExampleClass {
    public void myTestMethod() {
        CollectionBuilder collectionBuilder= new CollectionBuilder(CollectionType.HashSet);
        collectionBuilder.addValues(MyEnum.values()).build();
    }
}

public class CollectionBuilder {
    List<?> arrayList = Collections.EMPTY_LIST;
    Set<?> hashSet = Collections.EMPTY_SET;

    CollectionType collectionState = CollectionType.Undefined;
    HashMap<CollectionType, Collection<?>> collections;

    public CollectionBuilder(CollectionType type) {
        newCollection(type);
    }

    private void newCollection(CollectionType type) {
        switch(type) {
            case ArrayList:
                arrayList = new ArrayList<>();
                collectionState = CollectionType.ArrayList;
                addCollection(arrayList);
                break;
            case HashSet:
                hashSet = new HashSet<>();
                collectionState = CollectionType.HashSet;
                addCollection(hashSet);
                break;
        }
    }

    @SuppressWarnings (value="unchecked")
    public <T extends Enum<T>> CollectionBuilder addValues(T[] values) {
        Collection<T> collection = (Collection<T>) collections.get(collectionState);
        collection.addAll(List.of(values));
        return this;
    }

    @SuppressWarnings (value="unchecked")
    public <T> Collection<T> build() {
        return (Collection<T>) collections.get(collectionState);
    }

    private <T> void addCollection(Collection<T> collection) {
        collections.put(collectionState, collection);
    }
}


Relevante software en hardware die ik gebruik
IntelliJ IDEA, Gradle 7.2, Java 11, Spring Boot

Wat ik al gevonden of geprobeerd heb
Heel veel Google search, maar uiteindelijk kon ik het niet gevonden krijgen. Of ik snap gewoonweg niet hoe 'generics' werken in Java.

Beste antwoord (via Megabytes op 03-10-2021 23:56)


  • Hydra
  • Registratie: September 2000
  • Laatst online: 15-05 16:29
Dat kan ja, vraag je alleen af waarom je dat zou willen. Klinkt echt alsof je iets behoorlijk fout aan 't doen bent. En je loopt tegen het probleem aan dat Java type erasure heeft dus at runtime het generic type 'weg' is. Ik zou je vooral aanraden om eens goed na te denken waarom je dit nodig denkt te hebben. Dingen van verschillende types in 1 collection is vrijwel altijd een slecht idee.

Anywho; dit werkt:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
        var map = new HashMap<String, Collection<?>>();

        map.put("ArrayList", new ArrayList<>());
        map.put("Set", new HashSet<>());
        map.put("LinkedList", new LinkedList<>());
        map.put("OtherList", List.of("A", "B", "C"));

        map.forEach((k, v) -> {
            if(k.equals("OtherList")) {
                var list = (List<?>)v;
                System.out.println(list);
            }
        });

https://niels.nu

Alle reacties


Acties:
  • Beste antwoord
  • +2 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 15-05 16:29
Dat kan ja, vraag je alleen af waarom je dat zou willen. Klinkt echt alsof je iets behoorlijk fout aan 't doen bent. En je loopt tegen het probleem aan dat Java type erasure heeft dus at runtime het generic type 'weg' is. Ik zou je vooral aanraden om eens goed na te denken waarom je dit nodig denkt te hebben. Dingen van verschillende types in 1 collection is vrijwel altijd een slecht idee.

Anywho; dit werkt:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
        var map = new HashMap<String, Collection<?>>();

        map.put("ArrayList", new ArrayList<>());
        map.put("Set", new HashSet<>());
        map.put("LinkedList", new LinkedList<>());
        map.put("OtherList", List.of("A", "B", "C"));

        map.forEach((k, v) -> {
            if(k.equals("OtherList")) {
                var list = (List<?>)v;
                System.out.println(list);
            }
        });

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Megabytes
  • Registratie: Oktober 2021
  • Laatst online: 14-03-2022
Hydra schreef op zondag 3 oktober 2021 @ 17:44:
Dat kan ja, vraag je alleen af waarom je dat zou willen. Klinkt echt alsof je iets behoorlijk fout aan 't doen bent. En je loopt tegen het probleem aan dat Java type erasure heeft dus at runtime het generic type 'weg' is. Ik zou je vooral aanraden om eens goed na te denken waarom je dit nodig denkt te hebben. Dingen van verschillende types in 1 collection is vrijwel altijd een slecht idee.

Anywho; dit werkt:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
        var map = new HashMap<String, Collection<?>>();

        map.put("ArrayList", new ArrayList<>());
        map.put("Set", new HashSet<>());
        map.put("LinkedList", new LinkedList<>());
        map.put("OtherList", List.of("A", "B", "C"));

        map.forEach((k, v) -> {
            if(k.equals("OtherList")) {
                var list = (List<?>)v;
                System.out.println(list);
            }
        });
Bedankt voor je antwoord, het was meer van een uitdaging om het werkend te krijgen en of het überhaupt zou kunnen werken. De door jouw gedeelde code werkt inderdaad, maar dat is niet waar ik naar opzoek was. In de tussen tijd heb ik het zelf weten op te lossen door simpelweg in de constructor de volgende code te zetten:
code:
1
collections = new HashMap<>();


Tijdens het debuggen las ik zorgvuldig even het foutbericht nog eens en kwam ik erachter dat ik de lijst van de HashMap nooit instantieerde, daardoor kreeg ik een NullPointerException. Misschien is het volgende keer beter, vanuit mijn kant, ook eventuele errors te vermelden.. Alsnog bedankt voor je bericht, je hebt mij een ander soort inzicht gegeven met je gedeelde code.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 15-05 16:29
Megabytes schreef op zondag 3 oktober 2021 @ 23:55:
Misschien is het volgende keer beter, vanuit mijn kant, ook eventuele errors te vermelden.
De misschien kan je weg laten ;)

https://niels.nu