Collections Liste von Listen

Fricko

Mitglied
Hallo,

versuche gerade Java zu lernen und bin bei den Collections und Listen angekommen. Wollt jetzt ma versuchen Listen von Listen zu implementieren und dann versuchen die längste Liste auszugeben.
Habe mal versucht es zu programmieren, aber bin da eher skeptisch. Vll kann mir jemand mein Code verbessern und die Fehler erläutern. Kenn mich noch nicht so damit aus. Vielen Dank schonmal.
Java:
import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		ArrayList<List> liste = new ArrayList<List>();
	
	public List Maximum(){	
		for(List s : liste){
			int max = 0;
			if(s.size()> max){
				max = s.size();
			} 
			return s;
		}
	}
}
}
 
Methoden beginnen mit kleinem Buchstaben, es sollte also maximum() heißen.

Außerdem was willst du zurückgeben ... die längste liste? Oder die max größe?

Die längste liste gibst du auf jeden Fall nicht zurück, sondern immer die erste.
 
Wenn Du mal auf Deutsch versuchst, schritweise zu beschreiben, was Dein Code macht, wirst Du merken, was daran Käse ist. So als Tipp, es mag zwar sinnvoll sein, sich max als Vergleichswert zu merken, aber innerhalb der for-Schleife? Und letztlich musst du über die komplette Liste iterieren. D.h. return von innerhalb der for-Schleife ist auch falsch. Und irgendwo musst du Dir auch noch die aktuell längste Liste merken, dann wirst Du merken, dass Du max garnicht brauchst...
 
Die Größe selbst musst du dir nicht merken, sondern das Element, zu dem diese gehört. Also leg dir eine Variable maxList außerhalb der Schleife an, in die zu zunächst das erste Element reinpackst. Dann machst du mit jedem Schleifendruchlauf den test, ob die aktuelle Listenlänge größer als das bisherige Maximum ist und ersetzt ggf. die maxListe mit diesem aktuellen Element. Zum Schluss (NACH Verlassen der Schleife) gibst du maxListe zurück.
 
Dann nimm doch einfach irgendeine List Implementierung und erweitere diese um deine spezielle MaximumMethode:
Java:
package javaforum;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Main {

    static class SpezielleListe extends LinkedList<List> {

        List getMax() {
            if (isEmpty()) {
                return null;
            }
            Iterator<List> iter = iterator();
            List max = iter.next();
            while (iter.hasNext()) {
                List next = iter.next();
                if (next.size() > max.size()) {
                    max = next;
                }
            }
            return max;
        }
    }

    public static void main(String[] args) {
        SpezielleListe sl = new SpezielleListe();
        for (int i = 0; i < 100; i++) {
            Integer[] ia = new Integer[(int) (Math.random() * 1001)];
            Arrays.fill(ia, i);
            sl.add(Arrays.asList(ia));
        }

        List max = sl.getMax();

        System.out.println(max.size());
        System.out.println(max);
    }
}
Müssten Werte nahe 1000 rauskommen, habe mich für LinkedList Erweiterung entschieden.

Edit: ...oder schreib eine Methode, die die längste Liste zurück gibt - oder eine andere Erweiterung, welche sich beim hinzufügen/entfernen merkt, welche Liste momentan die längste Liste ist
 
Zuletzt bearbeitet von einem Moderator:
Danke für die schnellen Antworten und sry für den ein oder anderen dummen Fehler bin noch am lernen =)
Hab es jetzt nochma versucht, vll kann mir da jemand wieder was zu schreiben. Vielen Dank.
Java:
import java.util.ArrayList;
import java.util.List;

public class Test {
	ArrayList<List> liste = new ArrayList<List>();
	
	public List maximum(){	
		List maxList = liste[0];
		for(List l : liste){
			if(l.size()> maxList.size()){
			maxList = l;	
			}
		} 
	return maxList;	 
	}
}

Ob man List maxList = liste[0] so schreiben kann, weiß ich nicht, vll kann dazu noch jemand was sagen.
 
Ja, sieht gut aus, nur hast du ein Attribut liste in deiner Klasse.

Zeile 8 kannst du nur so schreiben, wenn du sicherstellst, dass liste niemals keine Elemente enthält, sonst muss vorher geprüft werden, ob leer oder nicht.

Praktisch wäres, wenn man der Methode eine Liste mit Listen übergeben könnte.
 
Hallo,

wie meinst du dass ich ein Attribut liste in der Klasse habe. sry versteh die aussage nicht so =)

Ok, kannst du mir vll zeigen wie ich das vorher überprüfen kann, weil empty ist laut eclipse nicht definiert für den Typ ArrayList<List> oder wie könnte es man besser machen, weil bei liste[0] noch ein Fehler von eclipse angezeigt wird.
Sry wenn die Fragen vll etwas dumm gestellt sind, bin noch Anfänger =)
Schönen Abend noch.
 
Bei Collections kommst du an das Element an einem bestimmten Index per getMethode.

also statt
Code:
liste[0]
einfach
Code:
liste.get(0);
.

Gruß Vanny
 
Würde ich generell nicht machen.

Würde ich auch nicht so machen, ist für die Praxis auch vielleicht nicht tauglich, aber als ich den ersten Beitrag gelesen hatte:
Java:
public List Maximum(){
...dachte ich irrtümlich, es handle sich um eine Erweiterung von List.

Was du mit Komposition und Aggregation an dieser Stelle meinst, muss du nochmal erklären.

Jedenfalls jetzt erst mal BTT: Grundsätzlich gibt es zwei Vorgehensweisen: 1. Man merkt sich beim Hinzufügen/Entfernen immer die momentan längste Liste/das momentan größte Element oder man geht 2. alle Listen/Elemente durch und sucht die längste Liste/das größte Element.

3. Möglichkeit wäre, eine sortierte Datenstruktur zu verwenden.

@Fricko: Der Ansatz sieht gut aus, musst wie gesagt nur vorher prüfen, ob die Liste leer ist oder nicht, und du könntest daraus eine Klassenmethode/statische Methode machen, die nicht vom Kontext der Klasse/von einem konkreten Objekt abhängig ist.
 
Zuletzt bearbeitet von einem Moderator:
Solche Methoden sollte man möglichst allgemein machen so dass sie mit allem arbeiten was Collection implementiert. Z.B. so:

Java:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class Test {
	public static void main(String[] args) {
		List<String> arraylist = new ArrayList<String>();
		arraylist.add("A");
		List<String> linkedlist = new LinkedList<String>();
		linkedlist.add("B");
		linkedlist.add("C");
		List<List<String>> cofcs1 = new ArrayList<List<String>>();
		cofcs1.add(arraylist);
		cofcs1.add(linkedlist);
		System.out.println("Laengste Liste: " + max(cofcs1));
		
		Set<String> hashset = new HashSet<String>();
		hashset.add("D");
		Set<String> treeset = new TreeSet<String>();
		treeset.add("E");
		treeset.add("F");
		Set<Set<String>> cofcs2 = new HashSet<Set<String>>();
		cofcs2.add(hashset);
		cofcs2.add(treeset);
		System.out.println("Groesstes Set: " + max(cofcs2));
	}
	
	public static <T> Collection<T> max(Collection<? extends Collection<T>> cofcs) {
		Collection<T> max = null;
		int maxSize = -1;
		for(Collection<T> collection : cofcs) {
			int size = collection.size();
			if(max == null || size > maxSize) {
				max = collection;
				maxSize = size;
			}
		}
		return max;
	}
}
 
genau, das meinte ich auch. Dabei wurde sogar mit generics gearbeitet.

Trotzdem könnte man beim Hinzufügen/Entfernen die Länge der Liste/Collection speichern, dann müsste man sich aber für eine List/Collection Implementierung entscheiden -> ist unausweichlich
 
Was du mit Komposition und Aggregation an dieser Stelle meinst, muss du nochmal erklären.
in 99,9% der Faelle ist das nicht gut
Java:
public void MyList<T> extends LinkedList<T> {
}
und sollte man eher so machen
Java:
public void MyList<T> {
  private List<T> inner;
 
  public MyList(List<T> i) {
     inner = i;
   }
}
Komposition >> Vererbung. Zum einen ist es schlecht sich von einer konkreten Implementierung abhaengig zu machen und auch sonst bindet man sich zu stark an eine Struktur, Mit Komposition ist man wesentlich freier und fuer Verwender strikter
 
Stimmt, das wäre besser. Aber nochmal: Ich war anfangs der irrtümlichen Überzeugung, es würde nur um eine List Erweiterung gehen.
1000 Dank für die Wiederauffrischung^^
 
Hallo,
habe jetzt nochma meine "Version" hoffentlich nochmal verbessert.
Java:
import java.util.ArrayList;
import java.util.List;

public class Test {
	ArrayList<List> liste = new ArrayList<List>();
	
	public List maximum(){	
		if(liste.size() != 0){
			List maxList = liste.get(0);
			for(List l : liste){
				if(l.size()> maxList.size()){
						maxList = l;	
				}
			} 
		return maxList;	 
	}  else {
		return null;
		}
	}
}
Kann mir da jemand nochma jemand was zu sagen =) Vielen Dank
 
Schau doch nochmal oben in meinen Post die Zeilen 13 bis 24. Manche bevorzugen es, Iterator zu nehmen. Falls die Liste leer ist (myList.isEmpty()) kann sofort z.B. null zurückgegeben werden. Sonst siehts gut aus. 🙂
 
Mit dem Iterator des will ich eher vermeiden, sieht iwie komplizierter aus =)
Eclipse zeigt bei List immer noch eine Warnung an, hab deshalb mal als Generics Object hinzugefügt, da List ja einfach ma alle Elemente aufnehmen kann. Kann ma das so machen? Die Warnung ist damit auf jeden Fall weg. Außerdem wollte ich das ganze jetzt einfach ma mit net main methode testen. nur blick ich da noch nicht so ganz durch vll, kann mir das jemand vervollständigen? Vielen Dank nochmals für die tolle Hilfe hier.
Java:
import java.util.ArrayList;
import java.util.List;

public class Test {
	ArrayList<List<Object>> liste = new ArrayList<List<Object>>();

	public List<Object> maximum() {
		if (liste.isEmpty()) {
			return null; }
		else {
			List<Object> maxList = liste.get(0);
			for (List<Object> l : liste) {
				if (l.size() > maxList.size()) {
					maxList = l;
				}
			}
			return maxList;
		} 
	}
}

public class Main {

	public static void main(String[] args) {
		List<String> arraylist = new ArrayList<String>();
        arraylist.add("A");
        List<String> linkedlist = new LinkedList<String>();
        linkedlist.add("B");
        linkedlist.add("C");
        List<List> cofcs1 = new ArrayList<List>();
        cofcs1.add(arraylist);
        cofcs1.add(linkedlist);
        cofcs1.maximum();
}
}
The method maximum() is undefined for the type List<List>
 
Mit dem Iterator des will ich eher vermeiden, sieht iwie komplizierter aus =)

...das Problem ist einfach ohne Iterator, dass get(0), get(1) usw. -Aufrufe unter Umständen mehr Zeit benötigen...

Und (ist zwar nicht ganz OOP, aber egal) aus der Methode könntest du eine Klassenmethode machen (die static ist), die nicht von dem Attribut liste abhängig ist, sondern der eine Liste übergeben wird (die also einen Parameter vom Typ List oder Collection hat).
 
Mit dem Iterator des will ich eher vermeiden, sieht iwie komplizierter aus =)
Gaaaaanz schlechtes Argument 😀 Aber kompliziert finde ich die Iteraroren nicht, du musst nur wissen, welchen Datentyp deine Listen sammeln, dann geht das ganz einfach:
Java:
Iterator<Integer> i = List#iterator();
while (i.hasNext()) {
    int zahl = i.next();
}
V.a. das Durchlaufen und Prüfen, ob ein nächstes Element vorhanden ist, wird damit sehr schön sichtbar.
 
Also entweder Iterator verwenden (weil dann das nächste Element immer sofort gefunden wird/werden kann) oder Komposition/Aggregation verwenden, wobei sich beim Einfügen/Entfernen die längste Liste gemerkt wird.

Komposition/Aggregation hatte ich früher als HAT- bzw. KENNT-Beziehung kennengelernt, deshalb sagte mir das so erst mal nichts.
 

Zurück
Oben