2 dimensonaler Daten Speicher


melmager

Erfahrenes Mitglied
#1
Ich brauche ein zweidimensonalen Datenspeicher mit Strings.
Da die Daten wachsen können muss das ganze dynamisch gehen.

Fragt sich nur wie.

Array List währe meine erste Wahl - nur wie macht man eine Array list mit Arraylist ?

oder eine Arraylist mit normaler Array String - das ging schon mal beim ersten Versuch auch nicht direkt - vermutlich muss ich das Array in eine Classe packen und dann die Classe per Arraylist verwalten - oder ?

sprich wie macht mach am klügsten eine 2 dimensonales String Array das Dynamisch wachsen kann sowohl in der X wie auch in der Y achse ?
 

HonniCilest

Erfahrenes Mitglied
#2
Array List währe meine erste Wahl - nur wie macht man eine Array list mit Arraylist ?
Java:
ArrayList<ArrayList<String>> arraylist = new ArrayList<ArrayList<String>>();
Je nachdem in welche Richtung du erweitern willst:
Java:
arraylist.add(new ArrayList<String>());
oder
Java:
arraylist.get(index).add(string);
 
Zuletzt bearbeitet:

melmager

Erfahrenes Mitglied
#3
Erstmal danke - so wie es aussieht muss ich mir weiter gedanken um die innereren Datenstructur machen - ich habe noch keine gefunden die allen meinen Anprüchen wirklich gerecht wird

Sprich ich gehe in Gedanken immer noch einige Varianten durch - und mal muss ich auch mal zu Potte kommen :)
sonst wird das mit dem Programm nie was :-(
 

melmager

Erfahrenes Mitglied
#4
Code:
arraylist.get(index).add(5,string);
kann ich das so machen ohne das die 4. position angelegt wurde ?

und kann ich auf null abfragen

sprich ist das dann true:
Code:
if ( arraylist.getindex(index).get(4) == Null)
oder haut es mir bei nicht gefüllten Einträgen in einer Arraylist Exeptions um die Ohren ?

oder währe es bei leereinträgen besser mit leeren Strings zu arbeiten ?

also an Position 4 ein
Code:
arraylist.get(index).add("");
machen ? und dann bei der Abfrage nach "Nix Da Einträgen" über die String länge zu gehen ?

Zusatzfrage
arraylist.get(index).add(5,string);
was passiert wenn ein Eintrag 5 vorhanden ist ? schiebt er den alten Eintrag 5 automatisch nach Pos 6 ?

noch ein zusatz
Arrays.asList(strArray)

wie gehe ich denn damit um ? wie füge ich denn das Array as list in das arraylist ein ?

gegeben ist ein Inputstring den ich mit Split auseinanderhaue und das ergebnis soll dann in meine Array list eingefügt werden - eigendlich wollte ich das in eine Schleife machen, aber gehts auch in einem Rutsch ?

Code:
String test = "a1,b2,c3",
// und dann das ?
arraylist.get(index).add( Arrays.asList(test.split(",")));
ich glaube der letzte Teil müsste mit addAll gehen
und add sollte verschieben wenn eintrag vorhanden habe ich nun gelesen

ich habe mal wider meine Fragen zu schnell gepostet :-(
 
Zuletzt bearbeitet:
#5
Grundsätzlich muss man bei ArrayList die Bounds einhalten, ansonsten wird eine IndexOutOfBoundsException geworfen.

Die Antwort zur Frage "schiebt er den alten Eintrag 5 automatisch nach Pos 6 ?" ist ja. Sofern Du viele solcher Operationen hast, wäre es LinkedList performanter!

"ich glaube der letzte Teil müsste mit addAll gehen" trifft zu. Alle Elemente werden jedoch hinter den bereits vorhandenen angefügt.

Grundsätzlich muss angemerkt werden, dass mit Strings sparsam umgegangen werden sollte. Was musst Du überhaupt implementieren?
 

melmager

Erfahrenes Mitglied
#6
Grundsätzlich muss man bei ArrayList die Bounds einhalten, ansonsten wird eine IndexOutOfBoundsException geworfen.

Die Antwort zur Frage "schiebt er den alten Eintrag 5 automatisch nach Pos 6 ?" ist ja. Sofern Du viele solcher Operationen hast, wäre es LinkedList performanter!

"ich glaube der letzte Teil müsste mit addAll gehen" trifft zu. Alle Elemente werden jedoch hinter den bereits vorhandenen angefügt.

Grundsätzlich muss angemerkt werden, dass mit Strings sparsam umgegangen werden sollte. Was musst Du überhaupt implementieren?
Bounds bedeutet wenn ich Eine Arraylist anlege die defaultsmässig 10 Positionen hat geht nicht

add(11,"bla")

dat ist noch logisch :)

Warum mit Strings Sparsam umgehen ?

Ich könnte auch eine Classe machen mit den verschiedenen Werten die ich speichern will
Was zu speichern ist: Höhe,Dauer und ab und zu eine Option - dat ganze wird jeweils durch Zahlen und Buchstaben im String dargestellt.
- ich habe auch desshalb intern ein String gemacht, da ich das auch irgendwann auf die Festplatte speichern will und spätestens dann muss ich die Daten in etwas wandeln was man auf Disk schreiben kann - dat wird so einfacher. ausserdem muss eine Eingabemöglichkeit für die Daten über die Tastatur gegeben sein

Das ganze ist immer noch mein Musik Projekt - und im moment bin ich dabei die Noten eines Liedes intern zu speichern.
Beispiel : 4CQ bedeutet 4. Octave Note C , Viertelnote

Code:
// verkürtze Version
classe Note {
Int octave;
char note;
char typ;
}
währe die andre möglichkeit, aber dann müsste ich 3 Classen zusäzlich schreiben Eingabe2Note , Note2Disk , Disk2note um da auf die Strings zu kommen für die aussenwelt

So siehts im Moment aus

Jede Notenzeile ist eine ArrayList die eine Arraylist von Strings enthält
Die Strings selber stellen dann wie schon gesagt, eine Note da

Code:
 ArrayList<ArrayList<String>> bltlst = new ArrayList<ArrayList<String>>();
Im Moment haben die Noten eine Feste breite bei der Darstellung - ob das Langfristig eine gute Idee ist wird sich noch zeigen - da ich nebenbei auch die Noten Lerne kann ich das noch nicht beurteilen.

Eingegeben wurde:
4CQ,4DQ,4EQ,......4GI,4GI
Q= Viertelnote, I = Halbenote
der Eingabe String wird am Komma gesplittet und dat String Array an das ArrayList übergeben

Die Classe Zeichen arbeitet dann die Liste ab

da die Zeichenbreite für eine Note fest ist kann ich auch über ein MausEvent ermitteln welche Note angeklickt wurde - das ist der Teil an dem ich grade dran bin

------------------------------------------------------------------------

Man könnte natürlich auch Ein Classe NotenZeile machen die eine Y Position hat, Einen NotenSchlüssel und eine ArrayList verwaltet von Noten. Diese Notenzeile liegt auch auf eine Arraylist die durch die Haupt Classe NotenBlatt verwaltet wird.
Die Noten selber haben Octave, Art, Typ sowie auch beim Zeichnen eine X Position auf der Zeile

Code:
// mal wider verkürzt
class NotenBlatt  {
ArrayList<NotenZeile> zeile = new ArrayList<NotenZeile>();
}

class Notenzeile  {
int Ypos;
char schluessel;
ArrayList<Note2paint> noten = new ArrayList<Note2paint>();
}

class Note  {
int octave;
char note;
char typ;
}

class Note2paint  extents Note {
int Xpos;
}
das währe warscheinlich der reine OOP ansatz ...

wobei ich dann Classen schreiben müsste die Meine DatenClasse verwalten würde - ich behaupte mal es währe unklug Classen zu speichern die Functionen hat .. und das würde dem OOP Gedanken verletzen so wie ich ihn verstanden habe

Frage die in dem Zusammenhang auftaucht: was ist denn Besser - die neue Arraylist so anlegen wie gepostet oder das im Constructor unterbringen ?

da ich grade den neuen Ansatz in Gedanken durchgehe - da ich auf eine Liste alles speichern kann - kann ich irgenwie beim Get (holen der Daten) emitteln ob das ein einfacher Darten Typ ist oder ein Array ?

Hintergrund: es können ja Noten gleichzeitig auftauchen da da würde sich ja ein Array von Note2paint anbieten
sprich auf der Liste können sowohl ein Objekt Note2paint liegen aber auch ein Array von Noten2paint .. wenn dat regelbar ist würde ich umschwenken auf das neue Datenspeicherkonzept.
 

Anhänge

Zuletzt bearbeitet von einem Moderator:
#7
Warum mit Strings Sparsam umgehen ?
Strings sind immutable d.h. bei jeder Änderung wird die Referenz zum aktuellen String aufgelöst und mit der Referenz des neuen Stringobjekts ersetzt. Wenn man ein paar neue Strings benötigt ist das kein Thema, wenn aber das ganze Programm darauf aufbaut, kann das zu Problemen führen, da String Literale vom gc nicht gelöscht werden.

Fachlich kann ich zu Deinen Anforderungen wenig beitragen, da ich kein Musiker bin. Jedenfalls ist die Empfehlung von J. Bloch "Avoid strings where other types are more appropriate" aus Effective Java hier anwendbar. Die Noten werden als int und char dargestellt, es besteht also keine Notwendigkeit, daraus Strings zu bilden.

wobei ich dann Classen schreiben müsste die Meine DatenClasse verwalten würde - ich behaupte mal es währe unklug Classen zu speichern die Functionen hat.. und das würde dem OOP Gedanken verletzen so wie ich ihn verstanden habe
Der OOP-Gedanke enthält das Prinzip der Kapselung, das genau Daten und Funktionen im gleichen Objekt verbindet.

Vielleicht ist es hilfreich, wenn Du im im Paket src.zip\javax\sound die Klassen unter die Lupe nimmst. Zudem würde ich die Speicherung von Noten als Stream und deren Darstellung auf einem Notenblatt trennen.
 

melmager

Erfahrenes Mitglied
#8
Der OOP-Gedanke enthält das Prinzip der Kapselung, das genau Daten und Funktionen im gleichen Objekt verbindet.

Vielleicht ist es hilfreich, wenn Du im im Paket src.zip\javax\sound die Klassen unter die Lupe nimmst. Zudem würde ich die Speicherung von Noten als Stream und deren Darstellung auf einem Notenblatt trennen.
Naja ein Stream ist es ja nicht und die Trennung da bin ich auch schon am grübeln wie mache ich dat am elegantesten

eine Liste mit einer Liste mit Array - auch wenn duch classen getrennt, macht dat ganze nicht wirklich übersichtlicher ...

ich knoble da schon ne ganze weile dran rum

im Moment denke über 2 Listen nach - eine einfache der Noten in der Reihenfolge ihres Auftretens im Lied
und eine andre Liste in der ich einfach speichere wo auf dem Bildschirm sie stehen

Code:
class Notenblatt {
ArrayList<NoteGfx> gfxblatt = new ArrayList<NoteGfx>();
}

class NoteGfx {
int xpos,ypos;
int link; // hier einfach den Indexwert der Note in der andren Tabelle liednoten rein
}

class Lied {
ArrayList<NoteData> liednoten = new ArrayList<NoteData>();
}

public class NoteData {
    char note,art;
    int octave, len;
    boolean is, extend;
}
 
Zuletzt bearbeitet:

melmager

Erfahrenes Mitglied
#9
Ich habe mittlerweile ein komplett neue Ansatz - eine erkenntnis : ich habe den OOP ansatz nicht wirklich verinnerlicht.

also der neue ansatz ist eine Trennung der Classen in Grafik und Song mit jeweils einer eigenen Liste und zwischen den beiden Classen wird sich über entsprechende Functionen ausgetauscht.


class Note {
int octave,note;
}

class Song {
// verwaltet die Noten in einer List
}

class GfxNotenblatt {
// verwaltet die Grafische oberfläche
// verwaltet positionen der Noten auf dem Bildschirm als Liste und hat zugriff auf die noten im Song über index
}

class Edit {
// fragt bei Mausklick den Index der ausgewählten Note an und holt die Note so aus dem Song um sie zu ändern und reicht sie zurück
}