Effizientester Weg um nach der Value einer verschachtelten Map aufzulösen

Diskutiere Effizientester Weg um nach der Value einer verschachtelten Map aufzulösen im Allgemeine Java-Themen Bereich.
Meeresgott

Meeresgott

Hallo,

ich habe eine Map in einer Map wobei der Schlüssel der ersten Map den Type der Value der zweiten Map beinhaltet. Der Schlüssel der zweiten Map ist der Wert nach dem ich auflösen möchte. Ich möchte alle Schlüssel der zweiten Map haben die eine Value vom Typ n haben.
Die im Beispiel gezeigte Methode getAllObjectsById(Long typeId):List<Long> macht genau das. Allerdings möchte ich auch nach allen Schlüsseln der zweiten Map fragen die einen Typ n und einen Typ m haben. Dies sollte eigentlich die Methode getAllObjectsById(Long[] typeId):List<Long> machen aber dies kumuliert nur die Ergebnisse aus der Suche nach n und der Suche nach m.

Ich habe es bis jetzt nicht geschaft, dass die Methode richtig auflöst. Habt ihr eine Idee wie die Umsetzung aussehen könnte?

Viele Grüße

Map<uuid1, Map<uuid2, Object>> testMap;
Java:
public class TestCase {

    private final Map<Long, Map<Long,ExampleObject>> exampleObjectByTypeId = new HashMap<>();

    @Test
    public void example() {

        ExampleObject e1 = new ExampleObject("data1",1);
        ExampleObject e2 = new ExampleObject("data2", 2);
        ExampleObject e3 = new ExampleObject("data3", 1);
        ExampleObject e4 = new ExampleObject("data4", 2);
        ExampleObject e5 = new ExampleObject("data5", 1);

        add(e1, 1L);
        add(e2, 1L);
        add(e3, 2L);
        add(e4, 2L);
        add(e5, 3L);

        for (Long id : getAllObjectsById(1L)){
            // Alle ausgeben die eine TypeId von 1L zugewiesen bekommen haben
            // Ausgabge ( 1  2  3 )
            System.out.print(String.format(" %d ",id));
        }

        System.out.println("\n -- ");

        for (Long id : getAllObjectsById(2L)){
            // Alle ausgeben die eine TypeId von 2L zugewiesen bekommen haben
            // Ausgabe ( 1  2 )
            System.out.print(String.format(" %d ",id));
        }

        System.out.println("\n -- ");

        for (Long id : getAllObjectsById(1L,2L)){
            // Alle ausgeben die eine TypeId von 1L und 2L zugewiesen bekommen haben
            // Ausgabe  (1  2  3  1  2 ) Sollte aber nur ( 1 2 ) sein
            System.out.print(String.format(" %d ",id));
        }

        System.out.println("\n -- ");

        remove(1);
        remove(2);
        remove(3);
    }



    public List<Long> getAllObjectsById(Long... typeIds){
        List<Long> retVal = new ArrayList<>();
        // Hier ist das Problem
        for (Long typeId : typeIds) {
            Map<Long, ExampleObject> exampleObjectMap = exampleObjectByTypeId.get(typeId);
            if (exampleObjectMap != null) {
                retVal.addAll(exampleObjectMap.keySet());
            }
        }
        return retVal;
    }

    public List<Long> getAllObjectsById(Long typeId) {
        Map<Long, ExampleObject> exampleObjectMap = exampleObjectByTypeId.get(typeId);
        if (exampleObjectMap != null) {
            return new ArrayList<>(exampleObjectMap.keySet());
        }
        return new ArrayList<>();
    }

    public void add(ExampleObject object, Long id) {
        exampleObjectByTypeId.computeIfAbsent(object.typeId, k -> new HashMap<>()).put(id, object);
    }

    public void remove(long id){
        exampleObjectByTypeId.remove(id);
    }

    private static class ExampleObject {
        public String someData;
        public long typeId;

        public ExampleObject(String someData, long typeId) {
            this.someData = someData;
            this.typeId = typeId;
        }
    }
}
 
mihe7

mihe7

Java:
    public Set<Long> getAllObjectsById(Long... typeIds){
        Set<Long> retVal = null;

        for (Long typeId : typeIds) {
            Map<Long, ExampleObject> exampleObjectMap = exampleObjectByTypeId.get(typeId);
            if (exampleObjectMap == null) {         
                break;
            }

            Set<Long> keys = exampleObjectMap.keySet();
            retVal = (retVal == null) ? new HashSet<>(keys) : retVal.retainAll(keys);
            if (retVal.isEmpty()) {
                break;
            }
        }
        return (retVal == null) ? new HashSet<>() : retVal;
    }
 
Meeresgott

Meeresgott

Danke! Der Code hat bei mir leider nicht funktioniert, da die Methode retainAll ein bool zurück gibt anstelle von einem Set.
Aber die Methode retainAll war genau das wonach ich gesucht habe!

Java:
public Set<Long> getAllObjectsById(Long... typeIds){
        Set<Long> retVal = new HashSet<>();

        for (Long typeId : typeIds) {

            Map<Long, ExampleObject> exampleObjectMap = exampleObjectByTypeId.get(typeId);
            if (exampleObjectMap == null) {
            // Siehe Edit 2  
            retVal.clear();
                break;
            }

            Set<Long> keys = exampleObjectMap.keySet();
            retVal.retainAll(keys);

            if (retVal.isEmpty() && !keys.isEmpty()) {
                retVal.addAll(keys);
            } else if (retVal.isEmpty()){
                break;
            }
        }
        return  retVal;
    }
Dieser Code funktioniert :D Vielen Dank!

EDIT1: funktioniert noch nicht die Methode getAllObjectsById(1L,2L,4L) liefert als Ergebnis (1,2). Da war ich wohl zu voreilig
EDIT2: ist die exampleObjectMap null, heißt es, dass das Ergebnis leer sein wird
 
Zuletzt bearbeitet:
Meeresgott

Meeresgott

Oh, sorry, da waren ein paar Leichtsinnsfehler drin.
Nichts zu entschuldigen, wir haben uns doch bestens verstanden ;)

Ich habe ein wenig mit der Lösung herum gespielt und denke ich werde diesen Code verwenden:

Java:
    // ....
    public Set<Long> getAllObjectsById(Long... typeIds){
        Set<Long> retVal = new HashSet<>(exampleObjectByTypeId.get(typeIds[0]).keySet());
        for (int i = 1; i < typeIds.length; i++) {
            retVal.retainAll(getAllObjectsById(typeIds[i]));
            if (retVal.isEmpty()) break;
        }
        return retVal;
    }

    public Set<Long> getAllObjectsById(Long typeId) {
        Map<Long, ExampleObject> exampleObjectMap = exampleObjectByTypeId.get(typeId);
        if (exampleObjectMap != null) {
            return new HashSet<>(exampleObjectMap.keySet());
        }
        return new HashSet<>();
    }
    // ....
Auch die Lösung mit den Sets finde ich gut. Bin da nicht drauf gekommen. - manchmal denkt man auch rechteckig
 
Thema: 

Effizientester Weg um nach der Value einer verschachtelten Map aufzulösen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben