Map-Strukturen

Cillo

Mitglied
// Das ist mein Code
Map<String, Map<String, String>> daten = new HashMap<String, Map<String, String>>();

daten.put("Prog 2", new HashMap<String, String>());
daten.get("Prog 2").put("Anna Alt", "3,3");
daten.get("Prog 2").put("Bob Berg", "2,3");
daten.get("Prog 2").put("Carla Carsten", "2,7");
daten.get("Prog 2").put("Daniel Dorf", "1,0");


daten.put("Mathe 2", new HashMap<String, String>());
daten.get("Mathe 2").put("Anna Alt", "2,3");
daten.get("Mathe 2").put("Bob Berg", "2,0");
daten.get("Mathe 2").put("Carla Carsten", "1,0");
daten.get("Mathe 2").put("Daniel Dorf", "1,7");

//Wie kann ich sowas erreichen ??

// Carla Carsten / Mathe 2
// Daniel Dorf / Prog 2
 
Zuletzt bearbeitet:

Neumi5694

Top Contributor
Über die Map "daten" kriegst du eine Map mit den Einträgen pro Person.
Java:
daten.get(Kursname)

Für jeden Key dieser Map erstellst du die oben beschriebene Ausgabe.
 

RegExs

Mitglied
//Wie kann ich sowas erreichen ??

// Carla Carsten / Mathe 2
// Daniel Dorf / Prog 2

Am "ehesten" wohl so:

Java:
import java.util.HashMap;
import java.util.Map;

public class Test1 {
    public static void main(String[] args) {
        // Das ist mein Code
        Map<String, Map<String, String>> daten = new HashMap<String, Map<String, String>>();

        daten.put("Prog 2", new HashMap<String, String>());
        daten.get("Prog 2").put("Anna Alt", "3,3");
        daten.get("Prog 2").put("Bob Berg", "2,3");
        daten.get("Prog 2").put("Carla Carsten", "2,7");
        daten.get("Prog 2").put("Daniel Dorf", "1,0");


        daten.put("Mathe 2", new HashMap<String, String>());
        daten.get("Mathe 2").put("Anna Alt", "2,3");
        daten.get("Mathe 2").put("Bob Berg", "2,0");
        daten.get("Mathe 2").put("Carla Carsten", "1,0");
        daten.get("Mathe 2").put("Daniel Dorf", "1,7");

        // Wie kann ich sowas erreichen ?

        // Carla Carsten / Mathe 2
        // Daniel Dorf / Prog 2

        for (Map.Entry<String, Map<String, String>> e : daten.entrySet()) {
            for (Map.Entry<String, String> e2 : e.getValue().entrySet()) {
                System.out.println(e2.getKey() + " / " + e.getKey());
            }
        }
    }
}
 

RegExs

Mitglied
Das sieht so aus, als würdest du besser mit Klassen arbeiten!
Das hab ich mir auch gedacht, aber das wäre erst der nächste Schritt ...

Noch ne Anmerkung: Man kann zwar über alle Map-Einträge iterieren, aber die Reihenfolge ist dabei nicht gegeben.

Außerdem hab ich obigen Code noch nicht end-optimiert... An ein paar Stellen gibt es noch Redundanzen.

@Cillo melde dich gern bei weiteren Fragen.
 

RegExs

Mitglied
Es stellt (in der OO) also noch nicht die Endlösung dar... Aber so etwas entwickelt sich sukzessive stufenweise, also nicht auf einen Schlag.

Wie man sinnvoll Klassen einsetzen kann, das wird wohl am "ehesten"(schon wieder :D ) in Büchern zu Design Pattern oÄ zu finden sein...
 

Cillo

Mitglied
// Wie kann ich sowas erreichen ?

// Carla Carsten / Mathe 2
// Daniel Dorf / Prog 2

// ich hatte vorher an sowas gedacht, aber geht nicht

List<String> myList = new ArrayList<String>(daten.keySet());
Collections.sort(myList);

for(String zeile : myList) {
String[] tokens = zeile.split(",");
String faechern = tokens[0];

String namen = tokens[1]; //Aber diese geht nicht
 

RegExs

Mitglied
Aber was ich vergessen habe, ist die Namen alphabetisch in der Console sein müssen
Nichts einfacher als das ...

Java:
        // Wie kann ich sowas erreichen ?

        // Carla Carsten / Mathe 2
        // Daniel Dorf / Prog 2

        TreeSet<Map.Entry<String, Map<String, String>>> entries = new TreeSet<>(Map.Entry.comparingByKey());
        entries.addAll(daten.entrySet());
        for (Map.Entry<String, Map<String, String>> e : entries) {
            TreeSet<Map.Entry<String, String>> entries2 = new TreeSet<>(Map.Entry.comparingByKey());
            entries2.addAll(e.getValue().entrySet());
            for (Map.Entry<String, String> e2 : entries2) {
                System.out.println(e2.getKey() + " / " + e.getKey());
            }
        }

Ausgabe
Code:
Anna Alt / Mathe 2
Bob Berg / Mathe 2
Carla Carsten / Mathe 2
Daniel Dorf / Mathe 2
Anna Alt / Prog 2
Bob Berg / Prog 2
Carla Carsten / Prog 2
Daniel Dorf / Prog 2

Soll denn auch noch gefiltert werden ?
 

RegExs

Mitglied
wie würdest du machen, wenn wir nur die Leute, die eine 1,0 haben, nehmen wollen ?
Na, ungefähr so:

Java:
            for (Map.Entry<String, String> e2 : entries2) {
                if (Double.parseDouble(e2.getValue().replace(',', '.')) <= 1.0)
                    System.out.println(e2.getKey() + " / " + e.getKey());
                else
                    System.out.println("The Biggest Loser: " + e2.getKey() + " / " + e.getKey());
            }
 

Cillo

Mitglied
ja, das ist eine Aufgabe für Uni

Wir haben schon Anfang eines Programms, in dem Namen der Studierenden, Fächern und Noten in einer verschachelten Map eingetragen sind:
Map<String, Map<String, String>> daten = new HashMap<String, Map<String, String>>();
daten.put("Prog 2", new HashMap());
daten.get("Prog 2").put("Anna Alt", "3,3");
daten.get("Prog 2").put("Bob Berg", "2,3");
daten.get("Prog 2").put("Carla Carsten", "2,7");
daten.get("Prog 2").put("Daniel Dorf", "1,0");
...

daten.put("Mathe 2", new HashMap());
daten.get("Mathe 2").put("Anna Alt", "2,3");
daten.get("Mathe 2").put("Bob Berg", "2,0");
daten.get("Mathe 2").put("Carla Carsten", "1,0");
daten.get("Mathe 2").put("Daniel Dorf", "1,7");
...
daten.put(...); // Weitere Faecher

Wir wissen im Voraus nicht, wie viele Studierende oder Fächer in den Daten es gibt.

Aufgabe
Ihre Aufgabe ist es, die Namen der Studierenden, die eine 1,0 erreicht haben, alphabetisch in der Console mit dem entsprechenden Fach zu drucken. Mit dem obigen Beispiel würde die Console-Ausgabe so aussehen:

Carla Carsten / Mathe 2
Daniel Dorf / Prog 2

Falls ein Studierende bei mehreren Fächern 1,0 erreicht hat, Sie brauchen nur irgendein Fach davon zu drucken.
 

Blender3D

Top Contributor
//Wie kann ich sowas erreichen ??

// Carla Carsten / Mathe 2
// Daniel Dorf / Prog 2
Java:
        ArrayList<String> noten = new ArrayList<>();
        daten.forEach((String fach, Map<String, String> data) -> data.forEach((String name, String note) -> {
            if (note.equals("1,0"))
                noten.add(name + " / " + fach);
        }));
        noten.sort(null);
        for (String s : noten)
            System.out.println(s);
 

mihe7

Top Contributor
Hey, die obligatorische Stream-Lösung fehlt noch :p
Java:
daten.entrySet().stream().
    flatMap(fach -> fach.getValue().entrySet().stream().
            filter(schueler -> schueler.getValue().equals("1,0")).
            map(schueler -> schueler.getKey() + " / " + fach.getKey())
    ).
    sorted().
    forEach(System.out::println);
 

KonradN

Super-Moderator
Mitarbeiter
Das ist aber doch das. Was ich mit hier generell denke … ein vernünftiger Ansatz wäre doch, Dich einmal hin zu setzen und Gedanken zu machen,
was man hat.
Dann, was man genau will.
Dann mit Stift und Papier den Weg überlegen … ohne Programmiersprache - rein in Worte
Dann kann man sich da überlegen, was für Daten man braucht, wie die zusammen hängen und so …

Wenn man dann so einen Weg sich überlegt hat, dann kann man das sehr schön aufbauen. Man kann es in Klassen / Datenstrukturen aufbauen oder man macht einfach nur Methoden, die auf den Daten basiert agieren ….
Dann kann auch eine Streams Lösung rauskommen - aber lesbarer mit Methoden denke ich mal.

Das Ergebnis ist also relativ offen bei der Vorgehensweise. Aber in ganz wenig Worten verpackt: es kommt immer zuerst das Verständnis der fachlichen Anforderung.

Aber ich wollte ja den Ratschlag, den ich bekommen habe, mir mehr zu Herzen nehmen und mich mehr zurück halten … ihr macht das alles schon!
 

Neue Themen


Oben