Frage zu Generics-Deklaration

markus2510

Mitglied
Hi !

Was ist an folgendem Konstrukt falsch ?

HashMap<String,T extends Comparable<T>>> _map=new HashMap<String,T extends Comparable<T>>>();

Sollte eigentlich eine HashMap mit beliebigen Comparables werden, d.h.

key1 => Float (3.8)
key2 => Integer (10)

usw.

lg, Markus
 
Erstmal kompiliert das Konstrukt nicht, weil du den generischen Parameter T nicht einfach so hinschreiben kannst, ohne ihn vorher definiert zu haben.
Der Teil hier muss also aus der Variablendefinition raus und ein generischer Parameter einer Klasse oder Methode werden:
Code:
T extends Comparable<T>
Dann bei der Map-Deklaration einfach nur noch T benutzen.

Mit T extends Comparable<T> sorgst Du dafür, dass die Comparables untereinander Typgleich sind. Das ist normalerweise auch erwünscht, weil z.B. ein String.compareTo(Integer) nicht funktionieren würde. Wenn du das Aufweichen möchtest (wofür es durchaus Gründe geben kann), musst Du das an genau der Stelle tun. Denkbare Varianten wären:
Code:
T extends Comparable<?>
oder
Code:
T extends Comparable<? super T>
 
Zuletzt bearbeitet von einem Moderator:
> mit beliebigen Comparables

na beliebige ja gerade nicht, sondern doch bestimmte Form von (Eigen-)Comparable,
dies kann man aber bei so einer Variablendeklaration nicht angeben, da sind Generics nicht ausdruckstark genug

viel mehr als
[c]HashMap<String, Comparable<?>> _map=new HashMap<String,Comparable<?>>();[/c]
kannst du einzeln nicht machen,
in deinem Beispiel stimmt übrigens allein die Anzahl < zu > nicht

eine kleine Check-Möglichkeit ist noch die Verwendung einer generischen Methode
Java:
public class Test2 {
    static HashMap<String, Comparable<?>> map = new HashMap<String, Comparable<?>>();

    public static void main(String[] args)  {
        X x = null;
        map.put("", new Float(3.8)); // gut
        map.put("", x); // keine Meldung
        
        put("", new Float(3.8)); // gut
        put("", x); // Fehler
    }
    
    static <T extends Comparable<T>> void put(String st, T value) {
        map.put(st, value);
    }

    abstract class X implements Comparable<String> {}
}
 
Hallo!

Nachfolgend der Code um den es geht: Die Klasse soll eine Zeile aus einer CSV-Datei abbilden. Mein Ziel ist es daß es dannach irgendwann möglich ist die CSV-Zeilen nach einem bestimmten Feld sortieren zu können.

Java:
public class CsvObject {
	private HashMap <String,Comparable<?>> _map=null;
	public static String compareField="id";
	
	public <T extends Comparable <T>> void setValue (String key,T value) {
		_map.put (key,value);
	}
	
	public Comparable<?> getValue (String key) {
		Comparable<?> value=_map.get(key);
		
		return (value);
	}
	
	// Wie krieg ich hier diese compareTo-Methode hin???
	
	public int compareTo (CsvObject o) {
		
	}
	
	public CsvObject () {
		_map=new HashMap<String,Comparable<?>>();
	}
	
	public static void main (String args []) {
		CsvObject o=new CsvObject ();
		o.setValue("id",new Integer (1));
		o.setValue("afloat",new Float (3.8));
		o.setValue("anint",new Integer (100));
		o.setValue("astring",new String ("Markus"));
		o.setValue("abool",new Boolean (true));
		System.out.println (o.getValue("anint"));
	}
}

Hab schon viel rumprobiert, aber ich krieg hier die compareTo-Methode einfach nicht hin ohne daß der Compiler was zu meckern hat. Kann mir irgendjemand helfen?

lg, Markus
 
was soll denn compareTo() leisten, wo hakt es?

einen Punkt den ich sehe: du kannst nicht erwarten, dass zu gleichen Keys in zwei verschiedenen Maps derselbe Comparable-Typ gefunden wird,
das leistet nun Generics absolut nicht, da überwiegt der Map-Charakter, einfache Objekte zu verwalten,

zu einem Key bekommst du Comparable<?> a und Comparable<?> b oder so,
die kannst du vergleichen indem du a.compareTo(b) aufrufst,
intern wird das schon einigermaßen gut vergleichen, von sauberen Generics bist du dazu aber gezwungenermaßen weit entfernt,
nix zu machen
 
Auf die Schnelle würde eine [c]Map<String, Object>[/c] machen und einen [c]Comparator<Object>[/c] schreiben, der jeden deiner Typen miteinander vergleichen kann: Erst einmal nach Typen (z.B. boolean kleiner als Zahlen kleiner als Strings) und innerhalb der Gruppen wie gewohnt.

Aufwendiger, aber langfristig die bessere Lösung wäre wohl, eine eigene Typ-Hierarchie zu bilden: Eine abstrakte Klasse [c]CsvType[/c], Unterklassen [c]CvsString[/c], [c]CsvBool[/c] und [c]CsvNumber[/c] u.s.w. Dann könnte deine Map [c]CsvType[/c]-Werte haben, und diese Klasse könnte wiederum [c]Comparable<CsvType>[/c] implementieren.
 

Neue Themen


Zurück
Oben