Collections Max Value einer Hashmap mit dazugehörigen Infos ausgeben

alxndr

Mitglied
Hallo Zusammen,

Ich habe 3 Klassen (Student, Kurs, Main) erstellt um entsprechende Objekte zu erstellen. Die Infos über Studenten sollen in eine Hashmap gelegt werden.

Folgendes Problem: Die Klasse Student besitzt eine Arraylist um die einzelnen Kurse den Studenten zuzuweisen. Am ende soll ich den Namen des Studenten mit den meisten Kursen ausgeben.

Ich habe mir überlegt dies über eine Arraylist zu machen die den Size-Wert der einzelnen Arraylists der Studenten speichert, was nicht funktioniert da ich nicht auf den Namen des Studenten zugreifen kann.

Habt ihr Vorschläge?

Java:
import java.util.*;

public class Main {

    public static void main(String[] args) {


        //Studenten
        Student s1 = new Student(224872, "Alfons", "Mueller");
        Student s2 = new Student(221256, "Alfred", "Schuster");
        Student s3 = new Student(284512,"Michael", "Klein");

        //Kurse
        Kurs k1 = new Kurs ("Germanistik", "Leopold Adam");
        Kurs k2 = new Kurs ("Wirtschaft","Knecht König");
        Kurs k3 = new Kurs("Thermodynamik","Heinz Baumann");
        Kurs k4 = new Kurs ("Informatik","Karl Laue");

        //Hashmap die Infos der Studenten mit einer Nummer, hier matrnr verknüpft
        Map<Integer, Student> studenten = new HashMap<>();
        studenten.put(s1.matrikelnummer, s1);
        studenten.put(s2.matrikelnummer, s2);
        studenten.put(s3.matrikelnummer, s3);


        //in die einzelnen arraylists der Studentenobjekte, Kurse legen
        s1.kurse.add(k1); s1.kurse.add(k2); s1.kurse.add(k3);
        s2.kurse.add(k4);
        s3.kurse.add(k1); s3.kurse.add(k4);


        //Variable, nimmt die Benutzereingabe auf
        int eingabe;

        //Scanner für Benutzereingabe
        Scanner input = new Scanner(System.in);

        System.out.println("Geben Sie eine Matrikelnummer ein: ");

        //weist der variablen eingabe den durch Scanner eingelesenen Wert zu
        eingabe=input.nextInt();

        //Überprüfen ob Matrilenummer vorhanden und ausgabe
        if (studenten.containsKey(eingabe)) {
            System.out.println("Matrikelnummer: "+ studenten.get(eingabe).matrikelnummer
                    +"\nName : "+ studenten.get(eingabe).name
                    +"\nVorname : "+ studenten.get(eingabe).vorname+"\n"
                    +"\nBelegte Kurse : ");

        //Kurse nach Name Sortieren
            Collections.sort(studenten.get(eingabe).kurse, new KurseSortieren());

        //durch Kurse loopen und ausgeben, sortiert
            for (Kurs k: studenten.get(eingabe).kurse){
                System.out.println(k.name+", "+k.dozent);
            }
        }

        else{
            System.out.println("Matrikelnummer nicht bekannt!");
        }

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

        //Gesamte Hashmap ausgeben
        for(Integer key : studenten.keySet())
        {
            System.out.println("Matrikelnummer: "+ studenten.get(key).matrikelnummer
                    +"\n"+"Name : "+ studenten.get(key).name
                    +"\n"+"Vorname : "+ studenten.get(key).vorname+"\n"
                    +"\n"+"Belegte Kurse : ");
            for (Kurs k: studenten.get(key).kurse){
            System.out.println(k.name+", "+k.dozent);
        }
            System.out.println("------------------------------------------------");

        }


        ArrayList<Integer> anzahlKurse = new ArrayList<>();
        anzahlKurse.add(s1.kurse.size());
        anzahlKurse.add(s2.kurse.size());
        anzahlKurse.add(s3.kurse.size());

        int maxKurse = Collections.max(anzahlKurse);

        System.out.println(maxKurse);


----------------------------------------------------------------------

public class Student {

    //Attribute
    protected int matrikelnummer;
    protected String vorname;
    protected String name;

    //Arraylist für Kurse
    ArrayList<Kurs> kurse = new ArrayList<Kurs>();

    //Konstruktor
    public Student(int matrnr, String vorname, String name){
        this.matrikelnummer=matrnr;
        this.vorname=vorname;
        this.name=name;
    }
}
---------------------------------------------------------------------

public class Kurs {

    //Attribute
    protected String name;
    protected String dozent;

    //Arraylist für Studenten
    ArrayList<Student> studenten;

    //Konstruktor
    public Kurs(String name, String dozent) {

        this.name=name;
        this.dozent=dozent;

    }

    //toString Methode wird überschrieben um den Namen auszugeben
    public String toString(){
        return name;
    }
}

-------------------------------------------------------------------

public class KurseSortieren implements Comparator<Kurs>{
    public int compare (Kurs k1, Kurs k2) {
        return k1.name.compareTo(k2.name);
    }
}
 

Flown

Administrator
Mitarbeiter
Du hast doch die Map<Integer, Student>. Iteriere doch einfach über die Map::values und suche dir den Studenten mit dem Maximum an Kursen heraus.
 

Flown

Administrator
Mitarbeiter
Pseudocode:
Code:
var result : Student = null;
for(Student s <- map.values) {
  if(result.isNull? or result.kurs.size < s.kurs.size) {
    result = s;
  }
}
println(result);
 
Zuletzt bearbeitet:

alxndr

Mitglied
Vielen Dank schonmal!

Habe es nun ausprobiert und bekomme immer den selben Namen, trotz Änderung der Kursanzahl raus, es wird immer nach der Größe der Matrikelnummer anstatt der Kurse sortiert
Java:
Student result = null;

        for(Student s : studenten.values()) {
            if (result == null || result.kurse.size() < result.kurse.size()) {
                result = s;
            }
        }

        System.out.println(result.name+" "+result.vorname);
 
Zuletzt bearbeitet:
X

Xyz1

Gast
Schmeiß' alle Studenten in eine Liste, sortiere absteigend nach kurse.size(), wähle das erste, fertig. :)
 
X

Xyz1

Gast
... Denn eine Map/Set kann nicht sortiert werden, eine List/Array hingegen schon! Comparator gut wählen.
 
X

Xyz1

Gast
@Flown : Das sind SortableSets/-Maps und keine klassischen Maps/Sets. Sortable bietet keine Vorteile gegenüber dem normalen sort(). Die kosten für den Overhead sind sogar höher. Also meine Antwort stimmt schon --- nur die Umsetzung hab ich nicht gemacht/gezeigt.
 

Flown

Administrator
Mitarbeiter
@DerWissende Deine Lösungsidee passt schon so. Ich habe nur die Aussage: "Map/Sets kann man nicht sortieren" in Frage gestellt und jetzt möchte ich wissen, warum die Tree-Implementierungen keine klassischen Maps/Sets sind. Was hat der Overhead jetzt damit zu tun?
 
X

Xyz1

Gast
Eine klassische Map ist immer eine HashMap, falls du das wissen wolltest. Und deren Implementierung ist Gegenstand "aktueller" Forschung, aber das wolltest du bestimmt nicht wissen. Wie es auch sei, für die Aufgabenstellung von alxndr ist das nicht relevant.
 

Meniskusschaden

Top Contributor
Ich ergänze das mal um meine (möglicherweise veraltete) Sichtweise, weil bisher teilweise nicht zwischen Maps und Sets unterschieden wurde.

Maps bzw. Sets sind Datenstrukturen zur Verwaltung von Schlüssel-Wert-Paaren (Maps) bzw. Mengen (Sets), die gewisse Eigenschaften und Operationen garantieren, aber keine Implementierungs- oder Laufzeitvorgaben machen. Bei beiden gehört das Sortieren nicht zu den Pflicht-Operationen, was aber nicht ausschliesst, dass eine konkrete Implementierung es trotzdem kann.

Eine HashMap ist wahrscheinlich die häufigste Map-Implementierung. Bei einer Hashmap kann man dann von bestimmten Eigenschaften ausgehen, die die Map noch nicht festgelegt hat, beispielsweise Zugriffszeit O(1) und - sofern vorhanden - ineffiziente Sortierung.

Bäume können meines Erachtens Implementierungen von Maps sein, typischer ist aber der Einsatz als Set.
 
X

Xyz1

Gast
Ich ergänze das mal um meine (möglicherweise veraltete) Sichtweise, weil bisher teilweise nicht zwischen Maps und Sets unterschieden wurde.

Neben Schlüssel noch Wert, kein großer Unterschied (außer in der Implementierung etwas).

keine Implementierungs- oder Laufzeitvorgaben machen

Eventuell mal in die Apidoc von Map/Set Interface abstract class schauen, vielleicht ist etwas dort angegeben.

ineffiziente Sortierung.

Ineffiziente? Wohl inkorrekte.^^

Sagen wir eine teilweise Sortierung.

Bäume als Sets oder Maps sind auch nicht unbedingt langsamer, nur sehr viel anders. Okay, etwas langsamer sind sie vielleicht schon. Ihr merkt schon, ich blubber etwas. :D

Summa summarum bewegen wir und ganz weit weg von der Fragestellung.^^
 

Meniskusschaden

Top Contributor
Neben Schlüssel noch Wert, kein großer Unterschied (außer in der Implementierung etwas).
Na ja, es werden schon unterschiedliche Operationen angeboten und damit gibt es auch einen Unterschied in der Schnittstelle.
Eventuell mal in die Apidoc von Map/Set Interface abstract class schauen, vielleicht ist etwas dort angegeben.
Ich habe eigentlich nicht die Java-Klassen gemeint, sondern die allgemein in der Informatik üblichen Datenstrukturen, wobei ich unterstelle, dass Java sich daran orientiert. Habe leider vergessen, das dazu zu schreiben. Im Java-Forum kann man sonst natürlich von der Java-Klassenbibliothek ausgehen.
Ineffiziente? Wohl inkorrekte.^^
Klar, wenn inkorrekt genügt, kann man auch mit HashMaps effizient sortieren.;)
 

dayaftereh

Top Contributor
Es kommt immer auf den Anwendungsfall drauf an. Will ich schnell und oft einene Stunden über seine Matrikelnummer finden, nutze ich eine Map.

Will dich oft den Student mit den meisten Kursen, so sollte ich eine sortierte Liste halten, wobei hier wieder die Frage ist wie oft lese oder schreibe ich auf die Liste.

Zudem kommt noch wie viele Stunden habe ich überhaupt. Passen alle in den Speicher ?
 
X

Xyz1

Gast
Minimale Rechtschreibung ist auch wichtig.....

Will ich den Besten habn, laufe ich natürlich einmal drüber. Will ich den zweit-, dritt-besten usw. habn, macht es schon Sinn, einmal zu sortieren, was nicht die Welt kostet.

Wie viele Studenten sind denn so üblich (innerhalb einer Fakultät)? Sagen wir 20'000 bis 80'000 --- DAS ist für ein modernes Rechnersystem ein Witz. Vielleicht kann ich das meiner Funkuhr auch noch beibringen.....

Offtopic:
Btw., noch als Hint., 1,0 ist auch nicht gleich 1,0 - dann ziehe ich halt Zusatzpunkte und soetwas heran. :D Ich weiß, einer von den Schlimmen. :/
/Offtopic
 
X

Xyz1

Gast
:):) Irgendwie drückst du dich schon seit Dienstag um eine konkrete Aussage zum Overhead. Jetzt schreib halt mal konkret auf wie du es machen würdest.

Jetzt ist auch etwas mehr Luft, und kein Würfelhusten. :)
Ich bin mal gaaaanz liep und schreibe ihm das komplett und zu 100 % auf:
Java:
package javaapplication;

import java.util.*;

/**
* @author DerWissende on 05/10/2016
*/
public class Temp {

    public static void main(String[] args) {

        //Studenten
        Student s1 = new Student(224872, "Alfons", "Mueller");
        Student s2 = new Student(221256, "Alfred", "Schuster");
        Student s3 = new Student(284512, "Michael", "Klein");

        //Kurse
        Kurs k1 = new Kurs("Germanistik", "Leopold Adam");
        Kurs k2 = new Kurs("Wirtschaft", "Knecht König");
        Kurs k3 = new Kurs("Thermodynamik", "Heinz Baumann");
        Kurs k4 = new Kurs("Informatik", "Karl Laue");

        //Hashmap die Infos der Studenten mit einer Nummer, hier matrnr verknüpft
        Map<Integer, Student> studenten = new HashMap<Integer, Student>();
        studenten.put(s1.matrikelnummer, s1);
        studenten.put(s2.matrikelnummer, s2);
        studenten.put(s3.matrikelnummer, s3);

        //in die einzelnen arraylists der Studentenobjekte, Kurse legen
        s1.kurse.add(k1);
        s1.kurse.add(k2);
        s1.kurse.add(k3);
        s2.kurse.add(k4);
        s3.kurse.add(k1);
        s3.kurse.add(k4);

        //Variable, nimmt die Benutzereingabe auf
        int eingabe;

        //Scanner für Benutzereingabe
        Scanner input = new Scanner(System.in);

        System.out.println("Geben Sie eine Matrikelnummer ein: ");

        //weist der variablen eingabe den durch Scanner eingelesenen Wert zu
        eingabe = input.nextInt();

        //Überprüfen ob Matrilenummer vorhanden und ausgabe
        if (studenten.containsKey(eingabe)) {
            System.out.println("Matrikelnummer: " + studenten.get(eingabe).matrikelnummer
                    + "\nName : " + studenten.get(eingabe).name
                    + "\nVorname : " + studenten.get(eingabe).vorname + "\n"
                    + "\nBelegte Kurse : ");

            //Kurse nach Name Sortieren
            Collections.sort(studenten.get(eingabe).kurse, new KurseSortieren());

            //durch Kurse loopen und ausgeben, sortiert
            for (Kurs k : studenten.get(eingabe).kurse) {
                System.out.println(k.name + ", " + k.dozent);
            }
        } else {
            System.out.println("Matrikelnummer nicht bekannt!");
        }

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

        //Gesamte Hashmap ausgeben
        for (Integer key : studenten.keySet()) {
            System.out.println("Matrikelnummer: " + studenten.get(key).matrikelnummer
                    + "\n" + "Name : " + studenten.get(key).name
                    + "\n" + "Vorname : " + studenten.get(key).vorname + "\n"
                    + "\n" + "Belegte Kurse : ");
            for (Kurs k : studenten.get(key).kurse) {
                System.out.println(k.name + ", " + k.dozent);
            }
            System.out.println("------------------------------------------------");

        }

        ArrayList<Student> studenten2 = new ArrayList<Student>();
        for (Map.Entry<Integer, Student> es : studenten.entrySet()) {
            studenten2.add(es.getValue());
        }
        studenten2.sort(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return Integer.compare(s2.kurse.size(), s1.kurse.size());
            }
        });
        for (int i = 0; i < 3; i++) {
            System.out.println("Platz " + (i + 1) + ":");
            System.out.println("studenten2.get(i) = " + studenten2.get(i));
        }
    }
}

class Student {

    int matrikelnummer;
    String vorname;
    String name;

    ArrayList<Kurs> kurse = new ArrayList<Kurs>();

    public Student(int matrnr, String vorname, String name) {
        this.matrikelnummer = matrnr;
        this.vorname = vorname;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" + "matrikelnummer=" + matrikelnummer + ", vorname=" + vorname + ", name=" + name + ", kurse=" + kurse + '}';
    }

}

class Kurs {

    String name;
    String dozent;

    ArrayList<Student> studenten;

    public Kurs(String name, String dozent) {
        this.name = name;
        this.dozent = dozent;
    }

    public String toString() {
        return name;
    }
}

class KurseSortieren implements Comparator<Kurs> {

    public int compare(Kurs k1, Kurs k2) {
        return k1.name.compareTo(k2.name);
    }
}

Ausgabe:
Code:
run:
Geben Sie eine Matrikelnummer ein:
224872
Matrikelnummer: 224872
Name : Mueller
Vorname : Alfons

Belegte Kurse :
Germanistik, Leopold Adam
Thermodynamik, Heinz Baumann
Wirtschaft, Knecht König
------------------------------------------------
Matrikelnummer: 284512
Name : Klein
Vorname : Michael

Belegte Kurse :
Germanistik, Leopold Adam
Informatik, Karl Laue
------------------------------------------------
Matrikelnummer: 224872
Name : Mueller
Vorname : Alfons

Belegte Kurse :
Germanistik, Leopold Adam
Thermodynamik, Heinz Baumann
Wirtschaft, Knecht König
------------------------------------------------
Matrikelnummer: 221256
Name : Schuster
Vorname : Alfred

Belegte Kurse :
Informatik, Karl Laue
------------------------------------------------
Platz 1:
studenten2.get(i) = Student{matrikelnummer=224872, vorname=Alfons, name=Mueller, kurse=[Germanistik, Thermodynamik, Wirtschaft]}
Platz 2:
studenten2.get(i) = Student{matrikelnummer=284512, vorname=Michael, name=Klein, kurse=[Germanistik, Informatik]}
Platz 3:
studenten2.get(i) = Student{matrikelnummer=221256, vorname=Alfred, name=Schuster, kurse=[Informatik]}
BUILD SUCCESSFUL (total time: 23 seconds)

q.e.d. Damit wäre die Aufgabe wohl gelöst. Der Studierende mit den meisten Kursen lautet: Alfons.

Was mich natürlich an der ganzen Sache stört: Die Matr.-Nr. sehen "vergleichsweise" echt aus.

Es wäre schade, wenn durch so eine "dumme" Aufgabe irgendjemand pikiert werden könnte.
 

Flown

Administrator
Mitarbeiter
Wow das hier in diesem Thema noch immer diskutiert wird. Wir können uns darauf einigen, dass alle Lösungsvorschläge gültig sind und je nach Anwendungsfall besser oder schlechter sind.
Brauch ich Ergebnisse öfter, würde ich zur Sortierung tendieren. Brauche ich es hingegen nur einmal dann such ich danach: O(n) < O(n*log n)

@DerWissende ich würde diese Frage nicht als "dumm" einstufen, sondern als "anfänger" Frage kategorisieren - klingt sonst ein wenig rüde

@Alle anderen Collections wie NavigableSet/-Map oder sogar SortedSet/-Map haben natürlich einen größeren Overhead als "normale" Maps/Sets oder sogar noch mehr als einfache Arrays. Das ist doch klar. Es kommt jetzt immer drauf an wieviel ich lese und schreibe. Kann man aber alles in der Dokumentation nachlesen (HIER - falls es jemanden interessiert).
 

Neue Themen


Oben