Collections Generische Klasse/Methoden

faulix

Mitglied
(Code unten)

Hallo,

ich möchte im Grunde über die zwei Set-Methoden jeweils die LinkedList speichern und über get-Methode die Daten auslesen. Dazu muss ich sie jedoch generisch in der Klasse speichern (dass man in der gesamten Klasse darauf zugreifen kann) und da habe ich die Probleme. Wie erzeuge ich die Variablen klassenweit generisch, denn so wie ich es mache muss ich oft Typ-Casting machen und bei einer Set-Methode geht dadurch der Comperator verloren, den ich jedoch benötige.

Ich hoffe ich konnte mein Problem darlegen und jemand kann mir etwas helfen.

Grüße faulix

Java:
package solutions;

import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import meinpaket.AbsSort;

public class Solution06 extends AbsSort {

	private LinkedList<?> classList;
	private Comparator<?> classComparator;
	
	@Override
	public <T> List<T> getData() {
		if (classList != null) {
			return this.classList;
		}
		return null;
	}

	@Override
	public Object getMax() {
		if (this.classList != null) {
			Iterator<K> items = this.classList.iterator();
			if (items.hasNext()) {
				K actualMax = items.next();
				while (items.hasNext()) {
					K item = items.next();
					if (this.classComparator.compare(actualMax, item) == -1) {
						actualMax = item;
					}
				}
				return actualMax;
			}
		}
		return null;
	}

	@Override
	public Object getMin() {
		if (this.classList != null) {
			Iterator<K> items = this.classList.iterator();
			if (items.hasNext()) {
				K actualMin = items.next();
				while (items.hasNext()) {
					K item = items.next();
					if (this.classComparator != null && this.classComparator.compare(actualMin, item) == 1) {
						actualMin = item;
					}
				}
				return actualMin;
			}
		}
		return null;
	}

	@Override
	public <T extends Comparable<T>> void setData(Collection<T> arg0) {
		if (arg0 != null) {
			this.classList = new LinkedList<K>();
			Iterator<T> items = arg0.iterator();
			while (items.hasNext()) {
				T item = items.next();
				this.classList.add((K) item);
			}
		}

	}

	@Override
	public <T> void setData(Collection<T> arg0, Comparator<T> arg1) {
		if (arg0 != null && arg1 != null) {
			this.classList = new LinkedList<K>();
			Iterator<T> items = arg0.iterator();
			while (items.hasNext()) {
				T item = items.next();
				this.classList.add((K) item);
			}
			this.classComparator = (Comparator<K>) arg1;
		}
	}

	@Override
	public void sort() {
		LinkedList<K> newList = new LinkedList<K>();
		while (this.classList != null && !this.classList.isEmpty())  {
			K actualMin = (K) this.getMin();
			newList.add(actualMin);
			this.classList.remove(actualMin);
		}
		this.classList.addAll(newList);
	}

	@Override
	public String[] getAuthors() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getTeam() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getVersion() {
		// TODO Auto-generated method stub
		return null;
	}

}
 
Die Basisklasse "AbsSort" könnte helfen. Spricht was gegen
Solution06<T> extends AbsSort
oder sogar
Solution06<T extends Comparable<? super T>> extends AbsSort
(und das T entsprechend bei den Listen verwenden) ?
 
Hallo,

ja aber ist nicht das grundsätzliche Problem, dass T in einem Fall von Comparable erbt und im anderen Fall nicht, diese Unterscheidung macht mir zu schaffen.

Und wenn ich das T nennen, überlagert es sich dann nicht mit den Variablen bei den Set- und Get-Methoden? Eclipse zeit hier und eine Hiding-Warning an.

Grüße faulix
 
In dieser Aufgabe nützen Generics eigentlich nichts (Hab sie vor ?2 Tagen schon mal hier gesehen).
Schlussendlich gibts 2 Varianten. Eine mit Comparable und eine mit dem Comparator.

Das einzige was du von der AbsSort weisst, ist das es entweder eine Liste von Comparables ist oder sonst eine Liste von irgendetwas mit dem passenden Comparator.

siehe JavaDoc der Aufgabe..ca

Code:
<T extends Comparable<T> setData(List<T> data)
oder
Code:
<T> setData(List<T> data, Comparator<T> com

Wenn du nun in der gleichen Methode das max holen willst, muss das 2-geteilt werden.
ca
Java:
 if (comparator != null) {
//testen mit comparator
} else {
//cast nach Comparable und testen
}
 
Hallo,

vielen Dank für diese Antwort, das hilft schon einmal etwas weiter. Nun Frage ich mich jedoch wie ich das in der Klasse speichern kann, sodass das Comparable nicht verloren geht.

Prinzipiell besteht mein Problem weiterhin: Wie erreiche ich das Generic bei den Klassenvariablen, denn dort habe ich den Typ ja noch nicht übergeben bekommen?

Vielen Dank für die Hilfe.

Grüße faulix

EDIT

Ich habe nun diese Version (unten).

In Zeile 75, 79, 88, 92, 94 gibt es nun Typprobleme (Type Mismatch), wieso und wie kann ich diese beheben, das verstehe ich nicht so ganz.

Java:
package solutions;

import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import de.tu_darmstadt.es.sopra.exercises.AbsSort;

public class Solution06<T extends Comparable<T>> extends AbsSort {

	private LinkedList<T> classList;
	private Comparator<T> classComparator;
	
	@Override
	public <T> List<T> getData() {
		if (classList != null) {
			return (List<T>) this.classList;
		}
		return null;
	}

	@Override
	public Object getMax() {
		if (this.classList != null) {
			Iterator<T> items = this.classList.iterator();
			if (items.hasNext()) {
				T actualMax = items.next();
				while (items.hasNext()) {
					T item = items.next();
					if (this.classComparator != null) {
						if (this.classComparator.compare(actualMax, item) == -1) {
							actualMax = item;
						}
					} else {
						if (item.compareTo(actualMax) == -1) {
							actualMax = item;
						}
					}
				}
				return actualMax;
			}
		}
		return null;
	}

	@Override
	public Object getMin() {
		if (this.classList != null) {
			Iterator<T> items = this.classList.iterator();
			if (items.hasNext()) {
				T actualMin = items.next();
				while (items.hasNext()) {
					T item = items.next();
					if (this.classComparator != null) {
						if (this.classComparator.compare(actualMin, item) == 1) {
							actualMin = item;
						}
					} else {
						if (item.compareTo(actualMin) == 1) {
							actualMin = item;
						}
					}
				}
				return actualMin;
			}
		}
		return null;
	}

	@Override
	public <T extends Comparable<T>> void setData(Collection<T> arg0) {
		if (arg0 != null) {
			this.classList = new LinkedList<T>();
			Iterator<T> items = arg0.iterator();
			while (items.hasNext()) {
				T item = items.next();
				this.classList.add(item);
			}
		}

	}

	@Override
	public <T> void setData(Collection<T> arg0, Comparator<T> arg1) {
		if (arg0 != null && arg1 != null) {
			this.classList = new LinkedList<K>();
			Iterator<T> items = arg0.iterator();
			while (items.hasNext()) {
				T item = items.next();
				this.classList.add((K) item);
			}
			this.classComparator = (Comparator<K>) arg1;
		}
	}

	@Override
	public void sort() {
		LinkedList<T> newList = new LinkedList<T>();
		while (this.classList != null && !this.classList.isEmpty())  {
			T actualMin = (T) this.getMin();
			newList.add(actualMin);
			this.classList.remove(actualMin);
		}
		this.classList.addAll(newList);
	}

	@Override
	public String[] getAuthors() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getTeam() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getVersion() {
		// TODO Auto-generated method stub
		return null;
	}

}
 
Zuletzt bearbeitet:
>sodass das Comparable nicht verloren geht.

Gar nicht.

Du weisst nur das es ein ? ist. Was du aber weisst:

- wenn der Comparator nicht null ist, hat es passende Objekte in der List
sonst
- wenn der Comparator null ist, sind Objekte, welche Comparable sind.

EDIT:
oder mit Code...hab mal das Abs Zeugs runtergezogen:
Java:
import java.util.Comparator;
import java.util.List;

public class Test { // extends AbsSort {

	private List<?> data;
	private Comparator<?> com;

	public <T> List<T> getData() {
		return (List<T>) data;
	}

	public Object getMax() {
		List<Object> list = getData();
		if (this.com != null) {
			// mit comparator Object vergleichen
		} else {
			// in der Liste sind comparables
		}
		return null;//max
	}

	public Object getMin() {
		List<Object> list = getData();
		if (this.com != null) {
			// mit comparator Object vergleichen
		} else {
			// in der Liste sind comparables
		}
		return null;//min
	}

	public <T extends Comparable<T>> void setData(List<T> data) {
		this.data = data;
		this.com = null;
	}

	public <T> void setData(List<T> data, Comparator<T> comp) {
		this.data = data;
		this.com = comp;
	}
}
 
Zuletzt bearbeitet:
>sodass das Comparable nicht verloren geht.

Gar nicht.

Du weisst nur das es ein ? ist. Was du aber weisst:

- wenn der Comparator nicht null ist, hat es passende Objekte in der List
sonst
- wenn der Comparator null ist, sind Objekte, welche Comparable sind.

Ich habe das mit dem Comparator denke ich nun gut ausgenutzt (siehe letzten Posting) und das funktioniert wahrscheinlich auch soweit.

Mein Problem ist nun in Zeile 75, 79, 88, 92, 94, dort gibt es nun Typprobleme (Type Mismatch). Das Problem ist wohl dass sich der Generictyp der Methode mit dem der Klasse überlagert, versteh ich das richtig? Wie kann man das Problem beheben?
 
Naja...K ist halt kein T..
K ist gar nix.

Es müsste ein T sein..aber dann passt eben die setData Methode nicht mehr.
Im Comparator Fall muss eben alles passen. Darum darf die Klasse auch nicht <T extends Comparable<T> sein.
Und die Listen auch nicht T (welche eigentlich in der super klasse schon da sind)
 
Hey, die TUD, ist mir ja gar nicht aufgefallen 🙂

Zugegeben, es ist wohl nicht im Sinne des Aufgabenstellers, dort
Solution06<T extends Comparable<T>>
zu verwenden, weil dadurch der Typ eingeschränkt wird. Für den allgemeinen Fall sollte man wohl den Comparator verwenden.

Jedenfalls wird mit den <T>s die vor den Methoden stehen natürlich das Klassen-<T> überdeckt. Es wäre wohl gut, (die Abstrakte Basisklasse und) die genaue Aufgabenstellung zu haben - speziell also, welche Methoden vorgegeben sind und nicht geändert werden dürfen, und ... wo kam in der ersten Variante das 'K' her? Und nicht zuletzt: Ist irgendwo explizit gesagt worden, dass der Code ohne unchecked- o.ä- Warnings compilieren muss?
 
>dass der Code ohne unchecked- o.ä- Warnings compilieren muss?

Das ist gar nicht möglich. Jemand hat mal vor 2 Tagen die JavaDoc der AbsSort gepostet. Sehr hässlich das ganze. Einmal cast nach Comparable und einmal cast nach Comparator. Jeweils ohne generics...
 
Hallo,

also DAS hat mir wirklich weiter geholfen. Ich habs halt einfach nicht gerafft, dass die Variablen schon in der Superklasse sind und sich somit das Problem der Erzeugung erst gar nicht ergibt.

Ich habe das nun dahingehend geändert, dass ich die Variablen der Superklasse nutze, beispielsweise so:
Java:
	public <T> void setData(Collection<T> arg0, Comparator<T> arg1) {
		if (arg0 != null && arg1 != null) {
			super.data = new LinkedList<T>();
			Iterator<T> items = arg0.iterator();
			while (items.hasNext()) {
				T item = items.next();
				super.data.add(item);
			}
			super.com = arg1;
		}
	}

Trotzdem habe ich folgendes Problem in Zeile 7: "The method add(capture#3-of ?) in the type List<capture#3-of ?> is not applicable for the arguments (T)"
Wenn ich ehrlich bin verstehe ich auch den Fehler nicht und weiß nicht so genau wo das Problem ist.

Hoffe ihr könnt mir auch dabei so super weiter helfen.

Grüße faulix
 
Code:
super.data = new ArrayList(arg0);

sollte reichen, wenn ich mich noch richtig erinnere..

EDIT:
Muss man die Methode überhaupt überschreiben?? war die abstract?
 
Zu einfach, so weit habe ich nicht gedacht.

Ja die sind leider alle abstract und somit muss ich sie definieren.

Nun habe ich noch bei den Min und Max-Methoden das Problem, dass ich einen Iterator erzeugen muss, ich jedoch nicht weiß mit welchem Typ, wie löse ich das am geschicktesten?
 
Code:
super.com.compare(actualMax, item)
Fehler: The method compare(capture#9-of ?, capture#9-of ?) in the type Comparator<capture#9-of ?> is not applicable for the arguments (Object, Object)

Was hat der nur immer für Probleme?

Ansonsten habe ich den Iterator nun mit get() umgangen indem ich get in eine for-Schleife mit den Indizies gepackt habe und diese mit Hilfe von size() durchlaufen lasse.
 
Java:
Comparator comparator =  (Comparator)super.comp;
comparator.compare(max, data)

Generics am besten gleich weglassen...dito dann zu Comparable casten..
 
Hab
Code:
Object item = super.data.get(index);
für den Comparable, aber funktioniert nicht und wüsste nicht wie ich da anders casten soll.
 
Java:
Object max = list.get(0);
for (Object object : getData()) {
	Comparable comparable = (Comparable)object;
	if (comparable.compareTo(max) > 0) {
		max = object;
	}
}
return max;

testen ob die liste nicht empty ist wäre gut
 
Zuletzt bearbeitet:
Code:
if (comp.compare(actualMin, item) == 1) {
Diese Zeilen wirft das hier aus: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

Was versucht er da zu Integer zu casten?
 
Ohne mehr präzisere Infos ist her VIEL Spekulation dabei. Ob das mit dem Fehler zusammenhängt, weiß ich nicht, aber es könnte sein: Wenn setData (ohne Comparator) aufgegrufen wird, muss eventuell ein schon gesetzter Comparator auf 'null' gesetzt werden.
 

Zurück
Oben