Entwickler-Ecke

Alle Sprachen - Alle Plattformen - Einen Comparator für ein Integerarray in Java entwickeln


Delphi-Laie - Mo 12.06.17 18:07
Titel: Einen Comparator für ein Integerarray in Java entwickeln
Hallo Programmierfreunde!

Zum (vorerst?) letzten Male habe ich ein Anliegen, das ich allein nicht gelöst bekomme.

Es geht mal wieder darum, einen Sortieralgorithmus zu starten, diesmal mal wieder in Java.

Ausgangspunkt war ein Eclipse-Projekt, in dem ich schon andere Sortieralgorithmen zum Laufen brachte (Anhang), es geht auf Eure dankenswerte Hilfe [https://www.entwickler-ecke.de/topic_JavaDatei+in+ein+JavaProjekt+einbinden+und+aufrufen_116255.html] zurück.

Für die Sortierprozedur "TimSort" in der Mainprozedur sind zwei Variablen zu übergeben - eine zu sortierende Datenstruktur und ein (Comparable-)Comparator. Zu meinem Erstaunen akzeptiert die Eclipse ein einfaches Integerarray als Parameter für die zu sortierenden Datenstruktur. Jedoch fangen beim Comparator die Probleme an. Trotz stundenlangen Lesens und Probierens fand ich bisher nichts, was die Eclipse zufriedenstellt. In meiner Not "stibitze" ich einen Comparator aus der schon implementierten Klasse


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
private static class ComparableComparator
    implements Comparator
    {
    public int compare(Object o1, Object o2)
      {
      Comparable c1 = (Comparable) o1;
      Comparable c2 = (Comparable) o2;
      return c1.compareTo(c2);
      }
    }


doch der funktioniert nicht, weil er sich auf Objekte allgemeiner Art bezieht, ich benötige hingegen einen Int-Comparator.

Auf den Datentyp "int" umgeschrieben:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
private static class ComparableComparator
    implements Comparator
  {
    public int compare(int o1, int o2)
    {
      Comparable c1 = (Comparable) o1;
      Comparable c2 = (Comparable) o2;
      return c1 < c2 ? -1 : c1 > c2 ? +1 : 0;
    }
  }


moniert der JIT-Compiler

Zitat:
The type HelloWorld.ComparableComparator must implement the inheritec abstract method Comparable.Comparator(Object, Object).


und außerdem die letzte Codezeile.

Eine andere aufgegabelte Version:


Quelltext
1:
2:
3:
4:
5:
6:
7:
class IntComparator implements Comparator<Integer> {

      @Override
      public int compare(Integer v1, Integer v2) {
          return v1 < v2 ? -1 : v1 > v2 ? +1 : 0;
      }
  }



wird zwar vom Compiler akzeptiert, funktioniert jedoch nicht als übergebbarer Comparator. Die Eclipse moniert:

Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)


Paßt also auch nicht.

Kurzum, jetzt bin ich mit meinem kleinen Latein am Ende.

Weiß jemand Hilfe zum Erfolg, bitte?

Vielen Dank und Gruß

Delphi-Laie


Delete - Mo 12.06.17 18:30

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delphi-Laie - Mo 12.06.17 18:49

Vielen Dank, Frühlingsrolle!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
eine TObjectList() wäre eine Alternative,


Eine Delphi-Objektliste? Ich quäle mich doch durch Java!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
oder eine eigenständige (statische) Klasse, die Objekte vergleicht.


Die ist doch schon enthalten:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
private static class ComparableComparator
    implements Comparator
    {
    public int compare(Object o1, Object o2)
      {
      Comparable c1 = (Comparable) o1;
      Comparable c2 = (Comparable) o2;
      return c1.compareTo(c2);
      }
    }


user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Hoppala, die möchtest den bestehenden Comparator() in Java für Integer anpassen?! Dafür bedarf es keienrlei Anpassungen, denn "Object" gilt für so ziemlich alles in Java, ebenso für Integer


Zu schön, um wahr zu sein. Bei mir klappt es natürlich nicht:


Quelltext
1:
2:
3:
int[] myArray = {5, 4, 3, 2, 1};     
Comparator c = new ComparableComparator(); 
TimSort.sort(myArray, c );


Der Compiler moniert an der letzten Zeile:

Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)


so, wie ich oben schon schrieb.

Ratloser Gruß

Delphi-Laie


Delete - Mo 12.06.17 19:31

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delphi-Laie - Mo 12.06.17 21:32

Hallo Frühlingsrolle, nochmals vielen Dank!

Die -1, 0 und +1 als Ergebnis der Vergleichsoperationen sind mir durchaus bekannt.


Java-Quelltext
1:
2:
TimSort.sort(zahlen, mc); // oder 
TimSort.sort(zahlen, new MyComparator());


Ja, und genau das ist ja das Problem: Die Eclipse akzeptiert diese Form der Comparator-Übergabe nicht. Links ist bei beiden Zeilen ein rotes Quadrat mit weißem Kreuz, also eine Fehlermeldung vorhanden. Bei beiden kann ich den Meldungstext (ich schreibe ihn nunmehr zum dritten Male):

Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)


abgreifen.

Trotz Deiner Mühe und Hilfsbereitschaft bin ich bisher, was die Lösung des eigentlichen Problems anbetrifft, nicht einen Zehntelmillimeter weitergekommen.

Dein Beispiel mit der Ausgabe funktioniert wenigstens. Nur ist diese Compare-Funktion anscheinend mit dem Integerarray inkompatibel.

Gruß

Delphi-Laie

Ergänzung: Vielleicht hilft es ja weiter, hier zu zeigen, was die automatische Codevervollständigung anbietet, wenn ich "TimSort." eingebe (Anhang): Sie möchte als Comparator ein "<? super T> c" haben. Was zum Teufel ist das?? c ist die Variable, die wohl beliebig sein kann, T steht für Timsort, der übrige Typ ist allerdings völlig kryptisch: Fragezeichen als Kurzform von if-else..."super" ist ein Schlüsselwort für die Vererbung..hm..also wohl dem "inherited" äquivalent.

nächste Ergänzung: Taucht weit oben in der TimSort-Klasse auf:


Java-Quelltext
1:
private final Comparator<? super T> c;                    


Delete - Mo 12.06.17 22:19

- Nachträglich durch die Entwickler-Ecke gelöscht -


jaenicke - Mo 12.06.17 22:23

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)
Das ist auch korrekt. IntComparator implementiert einen Comparator<Integer>, dein Array enthält statt Werten vom Typ Integer aber Werte vom Typ int.


Delphi-Laie - Mo 12.06.17 22:36

Frühlingsrolle, mir ist leider auch anhand Deiner Bilder nicht klar, was Du geändert hast, wenn das Projekt bei Dir funktioniert. Immerhin habe ich auch die Eclipse 4.6.2, scheint wohl noch die aktuelle Version zu sein.

Meinst Du mit "funktioniert", daß es mit TimSort compiliert und auch sortiert? Falls ja, könntest Du mir bitte Dein funktionierendes Projekt zukommen lassen?


Delphi-Laie - Mo 12.06.17 22:44

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)
Das ist auch korrekt. IntComparator implementiert einen Comparator<Integer>, dein Array enthält statt Werten vom Typ Integer aber Werte vom Typ int.


OK, tausend Dank, Sebastian!

Ich versuche mal, meine innere Explosion soweit wie möglich für mich zu behalten. "int" und "Integer", und dann auch noch zueinander inkompatibel, das ist einfach zu schön, um es schon nach wenigen Jahren vergessen zu haben.

Immerhin kann ich nun TimSort fehlerfrei mit Parametern aufrufen, zumindest im JIT-Compiler. Nun stehe ich allerdings vor dem Problem, ein Integer-Array dafür zu kreieren. Leider kann ich jetzt nicht


Quelltext
1:
integer zahlen[] = {5,4,3,2,1};                    


oder


Quelltext
1:
integer[] zahlen = {5,4,3,2,1};                    


schreiben, wäre ja auch zu schön gewesen.

Natürlich kann ich auch nicht


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
static class MyComparator
    implements Comparator<Integer>
  {
    @Override
    public int compare(Integer i1, Integer i2) {
        return Integer.compare(i1, i2);
    }
  }


von "integer" nach "int" umschreiben, denn das wäre ja eine mögliche Lösung gewesen, aber Java verweigert auch diese mir gegenüber hartnäckig. Die Welt könnte so herrlich schwierig sein, wenn sie nicht so wunderbar einfach wäre.

Vielen Dank und Grüße

Delphi-Laie


Delete - Mo 12.06.17 22:47

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delphi-Laie - Mo 12.06.17 23:01

Vielen Dank!

Warum


Quelltext
1:
Integer[] zahlen = {6, 3, 7, 5, 4};                    


bei Dir funktioniert, aber in meinem "HelloWorld" nicht (siehe meinen voherigen Beitrag), ist eines der vielen Rätsel. Das Geheimnis dahinter kann die Eclipse aber meinetwegen für sich behalten....

Leider kann ich Dein Projekt, nachdem ich es gerade so eingeladen bekam - endlich mal etwas ohne rote Fehlermeldungen an den Zeilenanfängen - nicht zum Laufen bringen. Drücke ich auf das Symbol "Weißer Pfeil auf grünem Kreis", erscheint nur ein Fehlermeldungsfenster:

"Editor does not contain a main type".

Herrlich!

Edit: Ein Fehler ist gefunden, es muß natürlich "Integer" statt "integer" heißen.


Delphi-Laie - Mo 12.06.17 23:03

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
The method sort(T[], Comparator <? super T> in the type TimSort is not applicable for the arguments (int[], Comparator)
Das ist auch korrekt. IntComparator implementiert einen Comparator<Integer>, dein Array enthält statt Werten vom Typ Integer aber Werte vom Typ int.


Noch eine Ergänzung dazu: Mir war eine "gewisse Inkompatibilität" auch klar, nur bezog ich diese ständig darauf, daß das eine zwei Integerwerte, das andere jedoch ein Integerarray ist (es wurde ja ständig "int[]" angezeigt.

Eine aussagekräftige Compilerfehlermeldung bezüglich Inkompatibilität zwischen "int" (und nicht "int[]) und "Integer" hätte Wunder gewirkt.


Delete - Mo 12.06.17 23:19

- Nachträglich durch die Entwickler-Ecke gelöscht -


Delphi-Laie - Mo 12.06.17 23:29

Nö, nicht nötig, ich habe jetzt Deinen entscheidenden Quelltext in mein "HelloWorld" kopiert. Es läuft!!

Das mit dem "integer" statt "Integer" geht natürlich völlig auf meine Kappe (diese Groß-Kleinschreibungsnachlässigkeit kommt daher, wenn man Programmiersprachen gewöhnt ist, denen das egal ist), aber der aus meiner Sicht nicht ausreichenden Fehlermeldung des Compilers bin ich immer noch gram.

Zum Debuggen werde ich die Eclipse ausreichend benutzen, das tat ich mit C-artigen Algorithmen schon einige Male, aber für eigenes Programmieren dem Delphi untreu werde ich nunmehr erst recht nicht.

Vielen Dank nochmal Euch beiden!


jaenicke - Di 13.06.17 07:13

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Zum Debuggen werde ich die Eclipse ausreichend benutzen, das tat ich mit C-artigen Algorithmen schon einige Male, aber für eigenes Programmieren dem Delphi untreu werde ich nunmehr erst recht nicht.
Ich persönlich benutze übrigens eher Netbeans. Eclipse habe ich im Studium benutzt, Addons eingebunden für Gui-Design usw., aber alles was ich brauche liefert Netbeans schon out-of-the-box. Ich habe nicht mehr genug Zeit um diese in die Konfiguration der IDE zu stecken. Deshalb bin ich da umgeschwenkt.