bekomme ich ein L, das von Label abgeleitet ist oder das Label selbst. Was muss ich schreiben, dass ich nur die Klassen bekomme, die Label implementieren, aber nicht das Label selbst sind, also so nach dem Motto <L (L != Label) extends Label>? Danke!
Okay das ist doof, aber vlt kann mir anders geholfen werden.
Also ich habe folgende Struktur:
Ein interface Label:
Java:
publicinterfaceLabel{StringtoString();doubletoDouble();/**
* Separates numeric values from Label in String Array and returns a
* {@link Sample} with the data from the array
*
* @param data the array containing the data that has not been separated yet
* @return the {@link Sample} containing the data from the array
* @throws IllegalArgumentException if there is not at least one numeric value
* and one Label in the array
*/<LextendsLabel>Sample<L>arrayToSample(String[] data)throwsIllegalArgumentException;/**
* returns a Label with value l
*
* @param l
* @return Label
*/<LextendsLabel>LparseLabel(String l);static<LextendsLabel>Lrandom()throwsIllegalAccessException{thrownewIllegalAccessException("May not call random() from super class");}}
Und verschiedene Enums die Label implementieren, da alle gleich aufgebaut sind hier mal eines als Beispiel:
Java:
publicenumBinaryLabelimplementsLabel{
POSITIVE, NEGATIVE;@OverridepublicStringtoString(){switch(this){case POSITIVE:return"POSITIVE";default:return"NEGATIVE";}}@OverridepublicdoubletoDouble(){switch(this){case NEGATIVE:return0d;default:return1d;}}staticBinaryLabelrandom(){return POSITIVE;}/**
* returns a {@link BinaryLabel} with value l
*
* @param l
* @return {@link BinaryLabel}
*/@Override@SuppressWarnings("unchecked")publicBinaryLabelparseLabel(String l){BinaryLabel label =BinaryLabel.POSITIVE;return(l.equals(label.toString())?BinaryLabel.POSITIVE :BinaryLabel.NEGATIVE);}/**
* Separates numeric values from {@link BinaryLabel} in String Array and returns
* a {@link Sample} with the data from the array
*
* @param data the array containing the data that has not been separated yet
* @return the {@link Sample} containing the data from the array
* @throws IllegalArgumentException if there is not at least one numeric value
* and one {@link BinaryLabel} in the array
*/@SuppressWarnings("unchecked")@OverridepublicSample<BinaryLabel>arrayToSample(String[] data)throwsIllegalArgumentException{double[] values;BinaryLabel[] labelArr;for(int i =0; i < data.length; i++){try{Double.parseDouble(data[i]);}catch(Exception e){if(i >1){
values =newdouble[i];for(int j =0; j < values.length; j++)
values[j]=Double.parseDouble(data[j]);}elsethrownewIllegalArgumentException("Expected at least one numeric value.");
labelArr =newBinaryLabel[data.length - values.length];if(labelArr.length >0)for(int j =0; j < labelArr.length; j++)
labelArr[j]=parseLabel(data[j + values.length]);elsethrownewIllegalArgumentException("Expected at least one label.");returnnewSample<BinaryLabel>(labelArr, values);}}thrownewIllegalArgumentException("Expected at least one label.");}}
Und nun stehe ich vor folgendem Sachverhalt: Ich habe einen CSVReader, der wie der Name schon sagt, daten aus einer CSV-Datei einlesen soll.
[CODE lang="java" highlight="9"]public class CSVReader<L extends Label> {
...
public SampleSet<L> read() throws IOException {
SampleSet<L> data = new SampleSet<L>();
String line = "";
In dem Code habe ich die Stelle, an der es scheitert hervorgehoben. Wie mache ich es, dass immer die arrayToSample-Methode des jeweils übergebenen L aufgerufen wird?
Da sagt der mir, "Cannot instantiate type L" was ja auch Sinn macht, da man ja kein objekt von einem Enum erstellen kann. Meine Frage ist also, wie kann ich die Methode arrayToSample des jeweiligen L aufrufen?
Dein L ist kein enum sondern ein generischer Typparameter, von denen kannst du auch kein Objekt erstellen. Deine Klasse braucht irgendwo her den Typ. Zb im Konstruktor
Java:
privateT t;publicCSVReader(T obj){
t = obj;}
Du kannst das T natürlich auch bei Methoden als Parameter setzen.
So hättest du eine Instanz von T , aber ob das Sinn in deinem Code macht weiss ich nicht. Ich tue mich sehr schwer den zu verstehen
Vlt ist der Code auch schlecht geschrieben....
Ich versuche mal zu beschreiben, was der tun soll:
Ich habe den CSVReader, der liest eine CSV-Datei ein, die wie folgt aussieht:
Jede Zeile besteht aus mindestens einem numerischen Wert und mindestens einem String, der später in ein Label umgewandelt wird
Jetzt lese ich diese Datei Zeile für Zeile aus, wobei jede Zeile als String-Array ausgegeben wird. Jede Zeile soll nun zu einem Sample<L extends Label> gemacht werden, wobei dieses Sample im Konstruktor einen Vektor mit den Zahlen und ein Array mit Labels bekommt. Der Konstruktor von Vector sieht so aus: public Vector(double... data) Für diesen Vorgang, also StringArray -> Sample habe ich die Methode arrayToSample die in der Datei des jeweiligen Label-Enums zu finden ist. Da ich verschiedene Enums habe die Labels repräsentieren stellt sich mir die Frage, wie ich am Ende ein Label-Array vom richtigen Typ in mein Sample bekomme.
Der üblichste Weg dafür wäre, eine Factory für die konkrete Label-Klasse zu übergeben.
Also das arrayToSample nicht in der Label-Klasse zu haben, sondern in einer LabelFactory, von der es dann für jede Art Label eine Subklasse gibt. Eine Instanz der Factory kannst du dann dem CsvReader übergeben.