# Strings mit compareto vergleichen und array sortieren



## theoneand (19. Jan 2012)

hallo zusammen,
also folgendes: hab zwar ähnliches hier schon gefunden, hat mir aber nich viel weitergeholfen....
ich hab ein array mit 3 parametern: matrnr, vorname, name
und ich soll dieses nach name sortieren.
wenn ich den namen als char mache geht alles wunderbar.... aber ein name hat meist nich einen buchstaben^^
deshalb wollte ich es mit strings machen. das problem ist aber, dass ich mit der compareto methode irgendwie die strings nich richtig vergleichen kann, da ich kein <= benutzen kann, mir ist auch klar warum, da nich der inhalt der strings verglichen wird, sondern das objekt.
das konnte ich von der doku in erfahrung bringen.
wie kann ich das ganze jetzt mit strings machen??
hier mein coding:


```
import java.util.*;

public class Student implements Comparable
{
	String matrnr ;
	String vorname;
	String name;
	
	Student (String matnr, String vorname, String name)
	{
		this.matrnr = matnr;
		this.vorname = vorname;
		this.name = name;
	}
	
	public int compareTo (Object oref)
	{
		
		Student sturef = (Student) oref;
		
		int i = 0;
		
		if (this.name <= sturef.name)
		{
			i = -1;
		}
		else
		{
			i = +1;
		}
		
		return i;

	}	
}
```



```
import java.util.Arrays;


public class Test_Student
{
	public static void main (String []args)
	{
		Student [] students = new Student [7];
		students [0] = new Student ("150", "hans", "zimmel");
		students [1] = new Student ("150", "hans", "yimmel");
		students [2] = new Student ("150", "hans", "ximmel");
		students [3] = new Student ("150", "hans", "wimmel");
		students [4] = new Student ("150", "hans", "vimmel");
		students [5] = new Student ("150", "hans", "uimmel");
		students [6] = new Student ("150", "hans", "timmel");
		
		
		Arrays.sort (students);
	/*	System.out.println (students[0].name);
		System.out.println (students [6].name);
		*/
		for(int i = 0; i <=6; i++)
		{
			System.out.println (students[i].name);
		}
		
		
	}
}
```


----------



## Gast2 (19. Jan 2012)

String implementiert Comparable.
Wenn du nach name sortieren willst reicht folgendes:

```
public int compareTo(Student s) {
  return name.compareTo(s.name);
}
```

EDIT:
Und das nächste mal bitte ne Überschrift wählen.


----------



## Kiri (19. Jan 2012)

so sollte es gehen:


```
public int compareTo (Object oref)
    {
        Student sturef = (Student) oref;
        return name.compareTo(sturef.name);
    }
```


----------



## theoneand (19. Jan 2012)

ja, habs auch gesehen, dass ich keinen titel drin hatte^^ habs geändert

ich steh glaub voll aufm schlauch.....
wenn ich deine compareto methode einsetze, sagt er mir:

The type Student must implement the inherited abstract method Comparable.compareTo(Object)

was is jetzt wieder falsch.....


```
import java.util.*;

public class Student implements Comparable
{
	String matrnr ;
	String vorname;
	String name;
	
	Student (String matnr, String vorname, String name)
	{
		this.matrnr = matnr;
		this.vorname = vorname;
		this.name = name;
	}
	



public int compareTo(Student s) {
	  return name.compareTo(s.name);
	}
}
```


----------



## theoneand (19. Jan 2012)

ach kacke^^ na klar, danke euch beiden vielmals


----------



## Gast2 (19. Jan 2012)

> The type Student must implement the inherited abstract method Comparable.compareTo(Object)


Du kannst 
	
	
	
	





```
Comparable<Student>
```
, dann sparst du dir den cast


----------



## theoneand (19. Jan 2012)

aber wozu brauch die zuweisung der ref noch??

Student sturef = (Student) oref;

hat sich erledigt, habs verstanden^^


----------



## HimBromBeere (19. Jan 2012)

Naja, weil der Methodenparameter ein Object ist und kein Student... oder was meinst du?

EDIT: Ich glaube, das war´s, was EikeB mit "unnötigen Cast" gemeint hat...


----------



## Wuast (8. Mai 2022)

Ich greife das mal auf (und "müll" das Forum mit meinen Fragen zu), weil ich da auch gerade dran bin.

Bei mir sind es nicht Studenten, sondern einfach Personenobjekte. Die will ich jetzt mit compareTo nach Nachnamen sortieren und (falls identisch) subsidiär nach Vornamen. 


```
@Override
    public int compareTo(Personen personenobjekt) {
        return this.nachname.compareTo(personenobjekt.getNachname());
    }
```

Ich habe jetzt zwei Personenobjekte:

```
Personen person1 = new Personen ("Herr", "Hans", "Müller");
Personen person2 = new Personen ("Herr", "Franz", "Meier");
```

liefert mir jetzt in der Ausgabe die Zahl 151. Ich hatte die Hoffnung, dass der mir nun zunächst das Objekt nennt, welches den Nachnamen ausspuckt, welches eher im Alphabet kommt, also "Herr Hans Meier". Taugt die compareTo dazu nicht bzw. wie sollte ich denn jetzt den int dahingehend nutzen?

Hoffe die Frage ist nicht völlig bescheuert aber ich checks noch nicht ganz.
Danke vorab


----------



## temi (9. Mai 2022)

Wuast hat gesagt.:


> augt die compareTo dazu nicht bzw. wie sollte ich denn jetzt den int dahingehend nutzen?
> 
> Hoffe die Frage ist nicht völlig bescheuert aber ich checks noch nicht ganz.


Lies die Doku: https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T-

Dieser Tipp gilt generell, denn die Dokumentation ist sehr gut und es ist wichtig damit zu arbeiten und auch arbeiten zu können.

Zu deiner Frage: Die Interpretation des Ergebnisses musst du erledigen. Der *positive* Wert von 151 (der genaue Wert ist irrelevant) sagt, dass _Müller_ "größer" ist als _Meier. _In deinem dazu gehörigen Algorithmus kannst du also schreiben:

```
if (thisPerson.compareTo(otherPerson) > 0) {
    // passende Tauschoperation(en)
}
```

Hinweis: Sollten deine Personen als Collection vorliegen, z. B. List<Person>, dann kannst du die Convenience-Methode sort() der Klasse Collections zum Sortieren verwenden. Für Arrays gibt es Ähnliches. Damit ersparst du es dir selbst einen Sortier-Algorithmus implementieren zu müssen.


----------



## Wuast (10. Mai 2022)

Danke. D.h. wenn das, was ich gepostet habe, schon alles war, ist die Sache erstmal noch recht nutzlos. xD ich fuchs mich nochmal rein


----------



## Wuast (12. Mai 2022)

temi hat gesagt.:


> Lies die Doku: https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T-


hab ich  klingt pausibel und so in etwa hatte ich es auch verstanden.
aber zu


temi hat gesagt.:


> Zu deiner Frage: Die Interpretation des Ergebnisses musst du erledigen. Der *positive* Wert von 151 (der genaue Wert ist irrelevant) sagt, dass _Müller_ "größer" ist als _Meier. _In deinem dazu gehörigen Algorithmus kannst du also schreiben:
> 
> ```
> if (thisPerson.compareTo(otherPerson) > 0) {
> ...


frage ich mich: So wie ich es verstanden habe, liefert die compareTo bei Strings lexikografische Ergebnisse?! Was heißt denn dann "größer"? Ich habe Schmitz und Meier compared und Schmitz ist "größer" (6), umgekehrt kommt wie zu erwarten -6 heraus. Aber *S*chmitz wäre in einer alphabetischen Reihenfolge doch hinter *M*eier. 

Muss man in der praktischen Anwendung also einmal ausprobieren, was herauskommt, um dann im Anschluss entsprechende Bedingungen zu formulieren? Will ich jetzt nur von zwei Namen wissen, welcher eher im Alphabet kommt, könnte es in diesem Fall doch etwas sein wie


```
@Override
    public int compareTo(Personen personenobjekt) {
        
        if (this.nachname.compareTo(personenobjekt.getNachname()) > 0) {
            System.out.println(personenobjekt.getNachname());
        }
        if (this.nachname.compareTo(personenobjekt.getNachname()) < 0) {
            System.out.println(this.nachname);
        }   
        if (this.nachname.compareTo(personenobjekt.getNachname()) == 0) {
            
        
            if (this.vorname.compareTo(personenobjekt.getVorname()) > 0){
                System.out.println(personenobjekt.getNachname());
            }
            if (this.vorname.compareTo(personenobjekt.getVorname()) < 0){
                System.out.println(this.nachname);
            }
        }
        
        return this.nachname.compareTo(personenobjekt.getNachname());
        
    }
```

Hier freue ich mich auch (noch) über einen Tipp, wie ich es schaffe, dass das Return sinnvoll löse, sodass es beim Methodenaufruf nur den Meier anzeigt als erster im Alphabet? Die Methode muss ja immer einen int zurückgeben.


----------



## KonradN (12. Mai 2022)

Wuast hat gesagt.:


> Ich habe Schmitz und Meier compared und Schmitz ist "größer" (6), umgekehrt kommt wie zu erwarten -6 heraus. Aber *S*chmitz wäre in einer alphabetischen Reihenfolge doch hinter *M*eier.


Und das ist ja auch, was das Ergebnis besagt.

Schauen wir mal Integer an und vergleichen die:
6 compareto 1 -> Ergebnis ist > 0 -> 6 ist größer als 1 .... Reihenfolge ist daher erst die 1 und dann die 6
"Schmitz" compareTo "Maier" -> Ergebnis ist > 0 -> "Schmitz" ist größer - die Reihenfolge ist also erst "Maier" und dann "Schmitz"



Wuast hat gesagt.:


> Hier freue ich mich auch (noch) über einen Tipp, wie ich es schaffe, dass das Return sinnvoll löse, sodass es beim Methodenaufruf nur den Meier anzeigt als erster im Alphabet? Die Methode muss ja immer einen int zurückgeben.


Was genau willst Du also?
- Eine Compare-to Methode die Vergleicht. Da ist erst einmal keine Ausgabe. (Du verkomplizierst damit ja die ganze Methode, wäre ich immer Vorsichtig mit. Klar, das kann als eine Art "Debugging" hilfreich sein aber immer überlegen, ob man dies wirklich braucht.
- Du willst Nachnamen vergleichen. Wenn diese gleich sind, willst Du die Vornamen vergleichen. Das Ergebnis ist dann der letzte Vergleich.

Das können wir noch in Pseudo-Code schreiben:
result := Vergleich Nachnamen
Wenn result == Gleichheit dann result := Vergleich Vornamen
Gibt result zurück

Das solltest Du jetzt 1:1 in Java Code umsetzen können denke ich mal.

Und prinzipiell hattest Du sowas in der Art auch schon - nur eben hattest Du erst einmal nur reine Anzeigen und Du hast die Vergleiche immer wieder aufgerufen, anstatt diese zu speichern. Du warst also extrem nah dran würde ich sagen


----------



## temi (12. Mai 2022)

Wuast hat gesagt.:


> Aber *S*chmitz wäre in einer alphabetischen Reihenfolge doch hinter *M*eier.


A ist _kleiner_ als B, ist _kleiner_ als C, usw., also ist die Reihenfolge *aufsteigend* A, B, C, D, E, F, G, ...

Das Verhalten sollte genauso sein, wie z. B. in einer Excel-Tabelle, die du _aufsteigend_ oder _absteigend_ sortierst.


----------



## Wuast (12. Mai 2022)

jetzt macht es auch für mich Sinn. danke für die Erläuterungen


----------

