Comparable Generic

ocsme

Top Contributor
Hallo,

ich verstehe nicht wieso hier ein Laufzeitfehler kommt.
Der Code:
Java:
import java.util.*;
public class Pair<X extends Comparable<X>,Y> {
    public X first;
    public Y second;
  
    public Pair() {
      
    }
  
    public Pair(X x, Y y) {
        first = x;
        second = y;
    }
  
    public int compareTo(Pair<X,Y> p) {
        return first.compareTo(p.first);
    }


public static void main(String[] args) {
      
        TreeSet<Pair<Integer,Integer>> ts = new TreeSet<Pair<Integer,Integer>>();
        Pair<Integer,Integer> p1 = new Pair<Integer,Integer>(1,2);
        ts.add(p1);
        System.out.println(ts.toString());      
    }
  
}

Die Exception:
Java:
Exception in thread "main" java.lang.ClassCastException: Pair cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1294)
    at java.util.TreeMap.put(TreeMap.java:538)
    at java.util.TreeSet.add(TreeSet.java:255)
    at Pair.main(Pair.java:24)

Kann mir das jemand erklären?
LG
 
Java:
package ???;

import java.util.TreeSet;

public class Pair<X extends Comparable<X>, Y  extends Comparable<Y>>
implements Comparable<Pair<X,Y>>
{
    public X first;
    public Y second;

    public Pair() {

    }

    public Pair(X x, Y y) {
        first = x;
        second = y;
    }

    @Override
    public int compareTo(Pair<X,Y> p) {
        return first.compareTo(p.first);
    }


    public static void main(String[] args)
    {
        TreeSet<Pair<Integer,Integer>> ts = new TreeSet<Pair<Integer,Integer>>();
        Pair<Integer,Integer> p1 = new Pair<Integer,Integer>(1,2);
        ts.add(p1);
        System.out.println(ts.toString());
    }

}

Damit sind die Member des Pair und das Pair selbst Comparable.

Wobei der zweite Pair-Member gar nicht Comparable sein muss.
 
Danke.
Jetzt kann ich Element in den TreeSet einfügen.
Doch wie bekomme ich den TreeSet ausgegeben?
😵

Verstehe das ganze nicht. Mein Versuch war das hier doch geht nicht! und mit einer for-each schleife bekomme ich es auch nicht hin 🙁

Java:
        Iterator<Pair> i = ss.iterator();
        while(i.hasNext()) {
            Pair p = i.next();
            System.out.println;
        }


ah so geht das ...
Java:
Iterator i = ss.iterator();
        while(i.hasNext()) {
            Pair p = (Pair) i.next();
            System.out.println(p.toString());
        }


Wie macht man das mit einer for-each schleife?
 
Warum ist das so?

Weil das TreeSet verlangt! Hatte ich auch vergessen!


Nun stehe ich vor zwei Problemen.
Erstens: Wie schreibt man das nun in einer for-each Schleife
Zweitens: soll noch eine Methode geschrieben werden und ich keine Idee habe wie man das hin bekommt.
Gesucht ist eine Methode die für eine gegebene Menge von abgeschlossenen Intervallen prüft ob es zwischen den Intervallen eine Lücke gibt (oder sets zwei benachbarte Intervalle einander überlappen) Signatur:
boolean existsGap(SortedSet<Pair<Float,Float>> inter { }
 
Zuletzt bearbeitet:
ah so geht das ...
Du willst vermutlich:
Java:
        Iterator<Pair<Integer,Integer>> i = ts.iterator();
        while(i.hasNext()) {
            Pair<Integer,Integer> p = i.next();
            System.out.println(p);
        }
oder eben:
Java:
for (Pair<Integer,Integer> p : ts) {
    System.out.println(p);
}
 
Zuletzt bearbeitet von einem Moderator:
Naja, schreib mal zwei Intervalle untereinander und überleg Dir, wann eine Lücke dazwischen ist.

Danke mihe7 wie immer 🙂
Werde das später mal probieren ob meine Idee klappt. Ich dachte nur es gäbe da ein Mathematischer Trick. Habe in meinen Bücher nach geschaut und auch gegooglet doch leider nichts gefunden.

Das Thema mit den Gernerics ist auch nicht meine Welt 🙁 naja Übung macht den MEISTER 😀 (nur bei mir nicht 😛)
Denn kann man auch dort alles mit Object machen und bekommt dann später die selben Fehler mit classCastException etc. wie bei den Arrays!

Java:
TreeNode<Integer> test = new TreeNode("1");
Durch die Fehlenden <> ist es vom Typ Object und ich kann munter ein String in mein Integer Container stecken 🙁 Da fliegt mir der Kopf weg wer soll das noch verstehen 🙁 😀

LG
 
Ich dachte nur es gäbe da ein Mathematischer Trick.
Nicht wirklich. Die Frage ist ganz einfach: wenn Du um 10:00 Uhr einen Parkschein für 1 Stunde ziehst, dann kannst Du bis 11:00 Uhr stehen bleiben (Intervall [10;11]). Um welche Uhrzeit kannst Du und um welche Zeit musst Du ein neues Ticket (=Intervall) kaufen, ohne dass Du (theoretisch) ohne gültiges Ticket parkst? Dann weißt Du, wann Du keine Lücken hast.

Durch die Fehlenden <> ist es vom Typ Object und ich kann munter ein String in mein Integer Container stecken
Die Zeile wird zu einem Compilerfehler führen.

Da fliegt mir der Kopf weg wer soll das noch verstehen 🙁😀
In der "Grundform" sind Generics doch relativ verständlich. In eine Kiste kann ich alles stecken, in eine Getränkekiste nur Flaschen. Die Funktionsweise ist aber immer die gleiche, die Kisten unterscheiden sich also nur vom Typ ihrer Elemente. Und der lässt sich mit einem Typparameter angeben. Kiste<Object> != Kiste<Flasche>
 
Nicht wirklich. Die Frage ist ganz einfach: wenn Du um 10:00 Uhr einen Parkschein für 1 Stunde ziehst, dann kannst Du bis 11:00 Uhr stehen bleiben (Intervall [10;11]). Um welche Uhrzeit kannst Du und um welche Zeit musst Du ein neues Ticket (=Intervall) kaufen, ohne dass Du (theoretisch) ohne gültiges Ticket parkst? Dann weißt Du, wann Du keine Lücken hast.

Also muss ich um 11 Uhr wieder hin für ein neues Ticket 🙂 Danke somit muss bei 2 Intervallen A = [a,b] B = [a,b] A.b = B.a sein 🙂

Die Zeile wird zu einem Compilerfehler führen.
Natürlich wird die Zeile übersetzt es kommt sogar das Stirng Object bei der Abfrage zurück:
Java:
        TreeNode<Integer> ti = new TreeNode("8");
        System.out.println(ti.getClassData());
class java.lang.String

In der "Grundform" sind Generics doch relativ verständlich. In eine Kiste kann ich alles stecken, in eine Getränkekiste nur Flaschen. Die Funktionsweise ist aber immer die gleiche, die Kisten unterscheiden sich also nur vom Typ ihrer Elemente. Und der lässt sich mit einem Typparameter angeben. Kiste<Object> != Kiste<Flasche>

Du solltest ein Buch schreiben 🙂 So wie du die Sachen erklärst versteht man es auch 🙂

LG
 
Also muss ich um 11 Uhr wieder hin für ein neues Ticket
Könntest Du Dir nicht auch um 10:45 Uhr ein neues Ticket für eine Stunde besorgen?

Natürlich wird die Zeile übersetzt
Mein Fehler.

Du solltest ein Buch schreiben 🙂 So wie du die Sachen erklärst versteht man es auch 🙂
a) keine Zeit, ich bin ja mit dem Forum hier beschäftigt 😛 und
b) finde ich Erklärungen anderer - auch hier im Forum - wesentlich besser.
 
Könntest Du Dir nicht auch um 10:45 Uhr ein neues Ticket für eine Stunde besorgen?
haha doch das ist mir gerade auch bewusst geworden als ich versucht habe das ganze echt scheiße zu programmieren 🙁

Java:
static boolean existsGap(SortedSet<Pair<Integer,Integer>> inter) {
        Iterator<Pair<Integer,Integer>> i = inter.iterator();
        Integer tmp=null;
        while(i.hasNext()) {
            Pair<Integer,Integer> p = i.next();
            if(tmp!=null)
                System.out.println(tmp.compareTo(p.second));
            tmp = p.second;
        }
        return false;
    }

Ich komme einfach nicht drauf wie man das machen soll bei einer beliebigen Menge 🙁
Als Hinweis steht dort noch man sollte Integer.Max_Value nutzen.
 
Ich weiß ich bin ein nerviger Geselle 😀

So hab es jetzt mal so gemacht:
Java:
static boolean existsGap(SortedSet<Pair<Integer,Integer>> inter) {
        Iterator<Pair<Integer,Integer>> i = inter.iterator();
        Integer tmp=null;
        while(i.hasNext()) {
            Pair<Integer,Integer> p = i.next();
            if(tmp!=null)
                if(tmp.compareTo(p.first) == -1)
                    return false;
                else if(tmp.compareTo(p.first) == 1) {
                     if(tmp.compareTo(p.second) > 0)
                        return false;
                }
            tmp = p.second;
        }
        return true;
    }

Ich glaube ich brauch nur abzufragen ob -1 bei der compareTo Methode raus kommt oder?
 
Zuletzt bearbeitet:
Weiß nicht ob es richtig ist aber habe heute auch keine Lust mehr 🙁
Hab es mal kurz mit Float versucht weil ich den Nachkommarteil testen wollte doch das übernimmt ja compareTo in Float für mich, wieder vergessen 😀 !!
Java:
    static boolean existsGap(SortedSet<Pair<Float,Float>> inter) {
        Iterator<Pair<Float,Float>> i = inter.iterator();
        Float tmp=null;
        while(i.hasNext()) {
            Pair<Float,Float> p = i.next();
            if(tmp!=null)
                if(tmp.compareTo(p.first) == -1)
                    return false;
            
            tmp = p.second;
        }
        return true;
    }
    
    public static void main(String[] args) {

        TreeSet<Pair<Float,Float>> ss = new TreeSet<Pair<Float,Float>>();
        Pair<Float,Float> p1 = new Pair<Float,Float>(-1f,11f);
        Pair<Float,Float> p2 = new Pair<Float,Float>(10.45f,11.45f);
        Pair<Float,Float> p3 = new Pair<Float,Float>(-45f,-.9f);

        ss.add(p1);
        ss.add(p2);
        ss.add(p3);

        System.out.println(existsGap(ss));
    }
 
Zuletzt bearbeitet von einem Moderator:
Wenn du weißt, welche Datentypen du hast, und du weißt, dass es Float oder Int's sind, dann kannst du einfach mit < und > vergleichen 😉 Nur für den genetischen Teil musst du CompareTo benutzen, dann brauchst du Methode aber nicht doppelt für Float und Integer.



Wenn ich das richtig sehe, hängst du immer noch bei der Prüfung, ob es keine Lücken gibt?
Aktuell gibts bei dir noch Fälle, in denen das fehlschlägt, zB mit [(0,11), (9,10), (11,12)].
 

Zurück
Oben