Programmdesign

java_noob43

Mitglied
Hi,

ich habe mich jetzt seit ein paar Wochen damit beschäftigt wie ich ein bestimmtestes Problem lösen kann und mir Grundkenntnisse der Programmierung angeeignet.
Nach diversem hin und herumprobieren möchte ich das Ganze jetzt strukturiert angehen und vor dem runter-coden (was sicher bei mir sicher sehr lange dauern wird) sicherstellen, dass die Programmstruktur und die Nutzung der Objektorientierung sinnvoll erfolgt und ich mich nicht vermeidbar verrenne.

Ich würde mich deshalb über etwas Input von erfahrenen Entwicklern zu folgendem Vorhaben freuen - da es mir sowohl an Programmierkenntnissen als auch an Erfahrung fehlt :rolleyes:.

Ich möchte in Roh-Daten vordefinierte Muster (vereinfacht: geometrische Figuren) suchen. Dann möchte ich zu den Mustern verschiedene Umgebungsvariablen zum Zeitpunkt des Auftretens des Muster untersuchen, um festzustellen welche Umgebungsvariablen sich bei welchen Mustern dazu eignen ein gutes Prognosemodell erstellen. Das geht ganz gut mit Statistik leider - habe ich nur Rohdaten, die Musterdefinition und diverse Theorien zu den relevanten Umgebungsvariablen die ich erst validieren muss.
D. h. mein zu lösendes Problem ist es aus den Rohdaten zunächst die Muster zu identifizieren und dann ebenfalls aus den Rohdaten und Mustern die Umgebungsvariablen zu erstellen. Erst anschließend kann ich statistische Methoden anwenden – die stat. Methoden sind für meine Anfrage unerheblich.

Der Roh-Datenpool umfasst ca. 20.000 Datenpunkte mit 6 Eigenschaften (Float und date).

Bei den Überlegungen dazu, wie die Muster (Vereinfacht: bspw. Rechteck, Dreiecke, …) zu erkennen sind habe ich mir einen Algorithmus überlegt, der zunächst darin besteht in allen Rohdaten die allgemeingültigen Teile der Muster zu identifizieren (vereinfacht Linien: nach rechts Linie, nach links absteigende Linie, horizontale Linie, …).
Ich möchte die Daten jeweils durch verschiedene Methoden jagen, die dann feststellen ob es Datenpunkte gibt die sich zu einem oder mehreren bestimmten Linientyp zuordnen lassen.

Meine Überlegung ist es nach der Identifikation eines Linientyps eine Klasse zu schreiben, welche die entsprechende Linienobjekte zu den Datenpunkten erzeugt.
Für jede identifizierte Linien soll dann noch ihre Güte in dem erzeugte Linienobjekt gespeichert werden – diese ist erforderlich um später die tolerierbare Ausreißerempfindlichkeit bzw. die tolerierbare dicke für eine Linie für das Prognosemodell bestimmen zu können.
Es wird je Linientyp n Ausprägungen geben.

Dann möchte ich prüfen, ob es Linien gibt die hinsichtlich Ihrer Lage die Bedingungen zur Klassifikation eines Musters (bspw. vereinfacht Rechteck) erfüllen. D. h. ich jage jetzt alle Linienobjekte durch verschiedene Methoden die dazu dienen die verschiedenen Muster zu identifizieren. Für jedes identifizierte Muster würde ich wiederum ein Objekt erzeugen und dazu die Eigenschaften aus den Linienobjekten übernehmen (bspw. Größe des Dreiecks, Anzahl der Ausreißer,….).
Theoretisch kann ein Muster Teil eines anderen Musters sein.


Ich habe mir eine Liste mit allen Datenpermutationen erstellt und bin mir ziemlich sicher, dass der Algorithmus an sich funktionieren sollte, was man schöner machen sollte würde mich natürlich dennoch interessieren.
  • Was sollte ich in der Designphase noch berücksichtigten?

Kurz-Form angedachter Programmaufbau:
  1. Main-Klasse
  2. importiert Rohdaten ein
  3. Analysiert Datenpunkte und identifiziert darin vordefinierte Linientypen
  4. Erzeugt alle identifizierten Linienobjekte
  5. Analysiert Linienobjekte und identifiziert darin vordefinierte Mustertypen
  6. Erzeugt alle identifizierten Musterobjekte und verschmilzt die Eigenschaften der zugrunde liegenden Linienobjekte
  7. Exportiert die Musterobjekte

  • Ist die Struktur des Programms unter den beschriebenen Bedingungen und insbesondere die Verwendung der angedachten Objekte sinnvoll?
 

AndiE

Top Contributor
Irgendwie nicht so richtig verständlich.

Punkte sind doch 0-dimensional. Wie können Sie dann Linien enthalten?

Ist das für dich selbst überprüfbar, was das Programm machen soll?

Kannst du mal ein Beispiel bringen, was du genau machen willst?
 

java_noob43

Mitglied
Danke das Du dich trotzdem durchgewühlt hast.
Ich baue mal ein "einfaches" Programmbeispiel, dann ist es wahrscheinlich einfacher ein Feedback zu geben.
Wenn es doof konzipiert ist habe ich hinterher bestimmt trotzdem was gelernt :)
Das wird wahrscheinlich ein bisschen dauern.
 

White_Fox

Top Contributor
Nach diversem hin und herumprobieren möchte ich das Ganze jetzt strukturiert angehen und vor dem runter-coden (was sicher bei mir sicher sehr lange dauern wird) sicherstellen, dass die Programmstruktur und die Nutzung der Objektorientierung sinnvoll erfolgt und ich mich nicht vermeidbar verrenne.
Lies etwas über Entwurfsmuster und versuche, es zu verstehen. Dekoratormuster, Beobachtermuster, Commandmuster, Adaptermuster, usw. Zum Schluß MVC. Ich kann dir das Buch "Entwurfsmuster von Kopf bis Fuß" wärmstens empfehlen.

Danach: einfach anfangen. Ein Versionskontrollsystem ist dein Freund.
Ich habe mich seit Ende letzten Jahres mit dergleichen Thematik herumgeschlagen und nach etwa einem halben Jahr das Ganze so gehabt wie ich es haben wollte. Ich habe bis dahin bestimmt drei Mal alles bis auf wenige Basisklassen alles gelöscht und wieder von vorn angefangen.
Ein ganz normaler Lernprozeß...
 

java_noob43

Mitglied
Danke für Eure Antworten. Ich glaube ich bin meine Problembeschreibung viel zu global und kompliziert angegangen.

Ich versuch mal einen Neustart - vergesst einfach mein Ursprungsbeitrag.
Auf Basis diverser Rohdatenprüfmethoden möchte ich aus Rohdaten dynamisch Objekte erzeugen, während das Programm die Rohdaten (liegen aktuell als String Array vor - die Datenkonvertierung sollte nicht das Problem sein) Datensatz für Datensatz durchläuft.

Die Rohdatenprüfmethoden können dazu führen, dass bei der Prüfung eines neuen Rohdatensatzes einem zuvor erzeugen Objekt weitere Daten hinzugefügt werden müssen.

Die Objekte sollen Daten vom Typ Float und Date enthalten.

Mein aktuelles Problem ist wie ich dynamisch Objekte erezugen, die unterschiedlich viele Daten beinhalten.
Ich habe schon rumgelesen und habe den Eindruck ich müsste dazu eine Art von Listen verwenden.
Mir ist jedoch nicht klar, wie ich gleichzeitig in einer Liste Objekte halten kann, denen wiederum unterschiedlich viele Datensätze zugeordnet sind. Kann man die Listen irgendwie Mehrdimensional gestalten?

Als Beispiel wähle ich mal, dass Größenmessergebnisse zu unterschiedlichen Zeitpunkten vorliegen.
Meine Rohdatenprüfmethoden erlauben mir einzelne Menschen zu identfizieren und diese möchte ich als Objekt erstellen und jedem dieser Menschen weitere aus meinen Rohdatenprüfmethoden abgeleitete Eigenschaften zuordnen.

Datum, Größe
2019-07-11 04-PM, 1.11
2019-09-11 05-PM, 1.12
2018-01-01 06-PM, 1.31
2019-01-05 07-PM, 1.42
2019-10-01 08-PM, 1.51

Nach Anwendung meiner Bedingungen ergibt sich, dass ich weiß (warum und wieso lass ich der EInfachheit halber mal weg)
Mensch 1
Wohlstand= reich
2019-07-11 04-PM, 1.11
2019-09-11 05-PM, 1.12

Mensch 2
Wohlstand= arm
2018-01-01 06-PM, 1.31
2019-01-05 07-PM, 1.42
2019-10-01 08-PM, 1.51
 

mihe7

Top Contributor
Mein aktuelles Problem ist wie ich dynamisch Objekte erezugen, die unterschiedlich viele Daten beinhalten.
Was heißt "unterschiedlich viele"? Sind die Attribute im Vorfeld nicht bekannt? Und wenn ja: was bringt das?

Grundsätzlich kannst Du natürlich dynamisch Daten in ein Objekt ablegen - mit einer Liste oder einer Map.

Mir ist jedoch nicht klar, wie ich gleichzeitig in einer Liste Objekte halten kann, denen wiederum unterschiedlich viele Datensätze zugeordnet sind.
Wieso sollen den Objekten Datensätze zugeordnet sein?

weitere aus meinen Rohdatenprüfmethoden abgeleitete Eigenschaften zuordnen.
Aber Du weißt doch, welche Eigenschaften das sind, oder nicht?

Entweder geht es hier um ein etwas ungewöhnliches Problem oder Du machst es zu kompliziert.
 

java_noob43

Mitglied
Was heißt "unterschiedlich viele"? Sind die Attribute im Vorfeld nicht bekannt? Und wenn ja: was bringt das?


Grundsätzlich kannst Du natürlich dynamisch Daten in ein Objekt ablegen - mit einer Liste oder einer Map.


Wieso sollen den Objekten Datensätze zugeordnet sein?


Aber Du weißt doch, welche Eigenschaften das sind, oder nicht?

Entweder geht es hier um ein etwas ungewöhnliches Problem oder Du machst es zu kompliziert.

Danke fürs wachrütteln.

Ich habe nochmal länger drüber nachgedacht. Ich denke es ist tatsächlich nicht erforderlich die Objekte mit unterschiedlich vielen Eigenschaften auszustatten - das wäre wohl eine sehr schlechte Struktur geworden.

Eigentlich reicht es für mein Objekt und die nachfolgenden Schritte im Programm die unterschiedlichen Ausprägungen zusammenzufassen. Also Erster Wert, letzter Wert, usw. damit haben dann alle Objekte die gleiche Anzahl von Eigenschaften und ich kann dennoch damit weiter arbeiten.

Leider hänge ich nun an einer anderen Stelle fest :-(.
Ich möchte zur Laufzeit bei der Analyse eines großen Roh-Datensatzes (liegt als ArrayList) vor, nachdem bestimmte Muster in dem Roh-Datensatz gefundenen wurden, Objekte erzeugen. Diesen neuerstellten Objekten möchte ich dann Eigenschaften zuweisen oder falls die Bedingungen es ergeben bestehende Objekte hinsichtlich Ihrer Eigenschaften aktualisieren.

Wie realisiert man am besten solche dynamische Objekterstellung?

Beispiel

Datenpunkt | Wert
1 | 100
2 | 101
3 | 99
4 | 101
5 | 105
6 | 101


Angenommen meine Musterbedinung würde sein, dass ich immer dann ein Objekt erzeuge möchte, wenn 3 aufeinanderfolge Datenpunkte jeweils einen höheren Wert als der vorherige aufweisen, wie kann man das konkret realisieren, dass die Objekte dynamisch erstellt werden?

In diesem speziellen Beispiel würde mein Erstes Objekt als Ersten Datenpunkt die 4 und als letzen Datenpunkt die 6 als Eigenschaften erhalten - weil ich das für folgende Schritte im Programmablauf benötige.

Es geht mir um dynamische Erzeugung des Objekts nicht um die Formulierung der Bedingungen meiner Mustererkennung - das ist nur ein vereinfachtes Beispiel ;-)
 

AndiE

Top Contributor
So richtig verstehe ich den Sinn noch nicht.

Nehmen wir mal an, ich habe eine Stechuhr, die mir eine Datei liefert, wo in jeder Zeile "Mitarbeiternummer, Datum/Zeit, Richtung" steht- also "123, 01.01.19, 8.00 PM, Z" bedeutet, dass Mitarbeiter nr. 123, zu der angegebenen Zeit den Bereich betreten hat. Nun kann ich also feststellen, dass es eine Anzahl Objekte der Klasse "Aufenthalt" gibt, die als Attribute, die Ankunft(Z ugang) und das Verlassen( W eggang) besitzt. Offensichtlich kann ich nun diese Objekte Objekten der Klasse "Mitarbeiter" zuordnen, so dass die Objekte der Klasse "Mitarbeiter" eine Liste aus Objekten der Klasse "Aufenthalt" beinhalten.

Kannst du das Problem, was du bearbeiten willst, an diesem Beispiel mal erklären? Und es zur Not so ausbauen, dass man nachvollziehen kannst, was du genau willst?
 

java_noob43

Mitglied
So richtig verstehe ich den Sinn noch nicht.

Nehmen wir mal an, ich habe eine Stechuhr, die mir eine Datei liefert, wo in jeder Zeile "Mitarbeiternummer, Datum/Zeit, Richtung" steht- also "123, 01.01.19, 8.00 PM, Z" bedeutet, dass Mitarbeiter nr. 123, zu der angegebenen Zeit den Bereich betreten hat. Nun kann ich also feststellen, dass es eine Anzahl Objekte der Klasse "Aufenthalt" gibt, die als Attribute, die Ankunft(Z ugang) und das Verlassen( W eggang) besitzt. Offensichtlich kann ich nun diese Objekte Objekten der Klasse "Mitarbeiter" zuordnen, so dass die Objekte der Klasse "Mitarbeiter" eine Liste aus Objekten der Klasse "Aufenthalt" beinhalten.

Kannst du das Problem, was du bearbeiten willst, an diesem Beispiel mal erklären? Und es zur Not so ausbauen, dass man nachvollziehen kannst, was du genau willst?

Irgendwie habe ich den Eindruck das Beispiel eignet sich nicht besonders gut für den Transfer meines Problems. Ich versuche mal die Unterschiede zu konkretisieren.
1. Meine Roh-Daten haben keine Mitarbeiternr., sondern nur einen Float-Werte und einen Zeitstempel. Es gibt pro Zeit nur einen Wert. Insofern könnte man dann vielleicht über die Zeit als Schlüßel gehen.
Mein Datensatz wäre eher
"01.01.19, 10.6"
"02.01.19, 11.6"
"03.01.19, 12.6"
"04.01.19, 10.6"
"05.01.19, 9.6"

Nehmen wir an eine Zeile repräsentiert die Arbeitszeit aller Mitarbeiter eines Unternehmens pro Werktag in Stunden.

2. Aus diesen Rohdaten möchte ich unterschiedliche Basis-Objekte erzeugen die bestimmten Basis-Bedingungen entsprechen.

Basis-Objekt1
Typ: Steigend
Max: 12,6
Stärke: 3 (Tage)
Startzeitpunkt: 01.01.19
Endezeitpunkt: 03.01.19

Basis-Objekt2
Typ: Fallend
Stärke: 3 (Tage)
Startzeitpunkt: 03.01.19
Endezeitpunkt: 05.01.19
Min: 9,6

Ich habe mir damit auf meine Rohdaten eine neue Perspektive erzeugt.

3. Mit dieser anderen Perspektive möchte ich dann im Programm weiterarbeiten, um verschiedene vordefinierte Thesen zu prüfen.

Die Thesen würde ich dann als Klasse implementieren.
Aus diesen Klassen würde ich dann Thesen-Objekte erzeugen, wenn es Basis-Objekte gibt welche die erforderlichen Bedinungen erfüllen.
Eine These könnte in Bezug auf Dein Beispiel sein auszuwerten, ob die Arbeitsstunden nach den unmittelbar hintereinander auftretenden Mustern vom Typ "fallend" und "steigend" einen Wert erreicht, dessen Maximum die Differenz zwischen Maximum und Minimum der Objekte 1 & 2 (max=12,6, min= 9,6 -> Differenz 3) ist.
In diesem Beispiel ergäbe sich Besipielsweise folgendes Thesen-Objekt (status am 05.01.19):

Thesen-Objekt

Typ: Next-Top
Erwarteter Wert: 3
Startzeitpunkt: 01.01.19
Wendezeitpunkt: 03.01.19
Endezeitpunkt: 05.01.19
Tatsächlicher Wert: NULL
Status: Inital

Der Eigenschaften des Thesenobjekts würden mit jedem neuen Rohdatensatz aktualisiert werden.
Als Status wären möglich Inital, bestätigt oder widerlegt.
Da der Rohdatensatz am 05.01.19 das Thesenobjekt erst erschaffen hat ist der Status inital.
Der tatsächliche Wert würde solange erhöht bis es Wert gibt, welcher unter dem Minimum von 9,6 liegt.


Anmerkung: Die Start-, Wende- Endezeitpunkte in den Objekten möchte ich speichern, um damit verknüpft aus den Rohdaten die Werte auslesen zu können und diese zu visualisieren.


Ich musste mich glaub ich recht weit von Deinem Beispiel entfernen und grübele noch darüber wie ich das besser beschreiben kann.

Hilft Dir das beim Verständniss?
 

mihe7

Top Contributor
In diesem speziellen Beispiel würde mein Erstes Objekt als Ersten Datenpunkt die 4 und als letzen Datenpunkt die 6 als Eigenschaften erhalten - weil ich das für folgende Schritte im Programmablauf benötige.
Die 6 verstehe ich ja noch, aber die 4?!? Die 99 aus der 3 ist doch niedriger als die 101 aus der 2 und die 100 aus der 1.

Ansonsten Ringbuffer mit 3 Elementen, Thema erledigt.
 
K

kneitzel

Gast
Nur um zu schauen, ob ich es richtig verstehe:

Du willst aus einer Serie von Elementen eine neue Serie von Elementen machen.
Dabei hast Du in so einem neuen Element:
- Typ: Steigend/Fallend
- Stärke: Anzahl der Elemente
- Start
- Ende
- min bzw max (In Abhängigkeit des Typs)

Und es ist nicht klar, wie viele Elemente in Aufsteigender oder Absteigender Folge kommen (Wenn das immer 3 wäre, dann müsstest Du den Counter nicht speichern, oder?)

Also da kannst Du Schritt für Schritt durch die Werte gehen. Am Anfang nimmst du die ersten zwei Werte obj1, obj2.

Typ ist am Anfang ASCENDING (obj1.value < obj2.value) oder DESCENDING
Startzeit ist timestamp obj1
Schwellwert ist obj2.value;
Counter ist 2
LetztesObjekt ist obj2

Dann gehst Du alle weiteren Elemente durch:
- Typ ist ASCENDING und obj.value ist größer/gleich Schwellwert oder DESCENDING und eben kleiner/gleich
==> Counter++, LetztesObjekt ist Obj
- Sonst:
==> Neues Objekt erstellen mit Counter, Schwellwert, Startwert, Endwert ist letztesObj.timestamp und Typ und speichern
==> Typ umsetzen, Counter = 2, Startzeit = LetzesObjekt.timestamp
- Schwellwert ist obj.value (Das immer machen!)
- LetztesObjekt = obj

So ein Algorithmus sollte das doch in etwa abhandeln. oder sehe ich das falsch?
 

java_noob43

Mitglied
Du willst aus einer Serie von Elementen eine neue Serie von Elementen machen.
Dabei hast Du in so einem neuen Element:
- Typ: Steigend/Fallend
- Stärke: Anzahl der Elemente
- Start
- Ende
- min bzw max (In Abhängigkeit des Typs)

genau.

Und es ist nicht klar, wie viele Elemente in Aufsteigender oder Absteigender Folge kommen (Wenn das immer 3 wäre, dann müsstest Du den Counter nicht speichern, oder?)

Im Prinzip ja - es ist nur leider noch komplexer.
Es gibt mehr als 2 Typen und ein Wert kann Ausgangspunkt für mehrere Elemente des gleichen und/oder verschiedener Typen sein.

Typ ist am Anfang ASCENDING (obj1.value < obj2.value) oder DESCENDING
Startzeit ist timestamp obj1
Schwellwert ist obj2.value;
Counter ist 2
LetztesObjekt ist obj2

Dann gehst Du alle weiteren Elemente durch:
- Typ ist ASCENDING und obj.value ist größer/gleich Schwellwert oder DESCENDING und eben kleiner/gleich
==> Counter++, LetztesObjekt ist Obj
- Sonst:
==> Neues Objekt erstellen mit Counter, Schwellwert, Startwert, Endwert ist letztesObj.timestamp und Typ und speichern
==> Typ umsetzen, Counter = 2, Startzeit = LetzesObjekt.timestamp
- Schwellwert ist obj.value (Das immer machen!)
- LetztesObjekt = obj

Also Dein Vorschlag ist, im main die Daten zu analysieren, die Elemente zu typisieren und dort einen counter mitlaufen zu lassen, den ich für die Erstellung jedes Elements verwende?

Wie kann ich einen Counter so in den Objektnamen einbinden, dass der sich der Objektname dynamisch erzeugen lässt?
Diese letzte Frage nehme ich aktuell als mein Hauptproblem war.
 
K

kneitzel

Gast
Also wo die Implementation wie zu finden ist, ist erst einmal dem Algorithmus egal. Aber ich würde generell davon absehen, irgendwas in main zu machen sondern ich würde generell zu einem objektorientierten Ansatz raten.

Was für weitere Typen gibt es? Ich hatte es so verstanden, dass das, was noch danach gekommen ist, dann die neu erstellten Instanzen benutzt. Aber generell kann der Vorgang auch weiter so umgesetzt werden. Ist aus meiner Sicht eine einfache Auswertung von Werten. Du hast einen Eingang, da kommt ein Wert nach dem anderen rein und daraus wird dann im Anschluss etwas gemacht. Ich habe sowas in der Vergangenheit "Eventbasiert" gemacht, d.h. Ich hatte einfach ein Objekt, das dann in einem Aufruf Werte entgegen genommen hat um diese dann zu verarbeiten. Wenn gewisse Dinge erfolgt sind, hat es dann andere Objekte informiert (die unbekannt sind, es war halt dann ein anderes Event).

Was Du mit "Counter im Objektnamen einbinden" meinst, verstehe ich nicht. Was für einen Objektnamen willst Du dynamisch erzeugen?
 

AndiE

Top Contributor
Ich finde immer noch, dass wir um den heißen Brei rumreden, solange wir nicht wissen, worum es geht.

Bis jetzt sehe ich nur eine Menge M mit m ( ist Element von M)={t,w1}, wobei t eine Zeit ist und e1 ein Wert. So kann ich nicht mal Intervalle festlegen, da mir dazu ein Indiz fehlt. also müsste m als m={id,t,w1) dargestellt werden. Diese Menge M wären die sogenannten Rohdaten und ein m wäre ein Rohdatensatz. Verbleibe ich bei m mit der obigen Festlegung, dann kann ich auch Teilmengen T, feststellen. Diese enthalten Elemente t mit i1 und i2, als Beginn und Ende des Intervalls, in dem eine Bedingung, formuliert als Satz s( s ist Element der Menge an Sätzen(Thesen) S), erfüllt wird. Das Element wäre also t={id,i1,i2,}. Nun muss man erst eine Beziehungsmenge B bilden, deren Elemente b die Teilmengen T(s)sind. Nun kann man eine Verkettungsmenge K bilden mit k={t,s}.

Damit erscheint aber die Erstellung neuer Werte wie in #6 nicht möglich. ( aus Längenwerten Vermögenslage feststellen).

Also gibbt es entweder noch weitere Werte. Sind die in m als Element von M enthalten. oder benutzt du noch eine
 

java_noob43

Mitglied
Vielen Dank für den Ansatz mit den Events.


Was für weitere Typen gibt es?
Im MvP 2.
Anschließend kommen dann noch 2-3 dazu je nachdem wie lange ich das betreibe ;-).

Ich hatte es so verstanden, dass das, was noch danach gekommen ist, dann die neu erstellten Instanzen benutzt.
Das ist korrekt.
Teilweise wird das Vorhandensein von 2 unterschiedlichen Elementen Bedinung dafür sein eine weiteres Element (These) zu erschaffen (Du meinst These = Instanz ?- ich möchte den Begriff der Instanz nicht vorschnell und falsch verwenden ).

Aber generell kann der Vorgang auch weiter so umgesetzt werden. Ist aus meiner Sicht eine einfache Auswertung von Werten. Du hast einen Eingang, da kommt ein Wert nach dem anderen rein und daraus wird dann im Anschluss etwas gemacht. Ich habe sowas in der Vergangenheit "Eventbasiert" gemacht, d.h. Ich hatte einfach ein Objekt, das dann in einem Aufruf Werte entgegen genommen hat um diese dann zu verarbeiten. Wenn gewisse Dinge erfolgt sind, hat es dann andere Objekte informiert (die unbekannt sind, es war halt dann ein anderes Event).

Ich habe mit Events noch gar keine Erfahrung und gar keine Kentniss, da werde ich jetzt mal recherchieren.

Was Du mit "Counter im Objektnamen einbinden" meinst, verstehe ich nicht. Was für einen Objektnamen willst Du dynamisch erzeugen?

Folgend mal ein Code-Beispiel (ich habe da jetzt nicht alle Bedingungen zu Ende programmiert), die Thesen konnte ich darin jetzt nicht unterbringen, weil ich auf meine Objekte nicht zugrifen kann wie ich das gerne möchte.
Der Compiler zeigt in den Zeilen in dennen ich die Objekte trend1 und trend2 erstelle die Meldung
"The value of the local variable trend1/2 is not used" an, obwohl die Println Anweisung aus der Objektklasse ausgeführt wird.
Was mach ich da falsch?

Code:
import java.util.ArrayList;


public class Program {
       static int currentValue;
       static int lastValue;
       static int valueBeforeLastValue;


          public static void main(String[] args) {
         
              //Timestamp-Beispiele erzeugen
              ArrayList<Integer> listeTimestamps = new ArrayList<Integer>();
              listeTimestamps.add(1);
              listeTimestamps.add(2);
              listeTimestamps.add(3);
              listeTimestamps.add(4);
              listeTimestamps.add(5);
           
             
              //Werte-Beispiele erzeugen
              ArrayList<Integer> listeWerte = new ArrayList<Integer>();
              listeWerte.add(12);
              listeWerte.add(13);
              listeWerte.add(14);
              listeWerte.add(9);
              listeWerte.add(7);

             
              //Schleife zum Durchlauf aller Rohdaten-Werte, um den Objekten Trend den das Attribut Typ (auf- oder absteigend) zuzuordnen
              for (int i =0; i < listeWerte.size(); i++) {                  
                   if (i == 0)       {
                             currentValue = listeWerte.get(i);  
                           }
                               
                   else if (i == 1) {
                       lastValue = currentValue;
                       currentValue = listeWerte.get(i);
                       }
                       
                   else if (i >= 2) {
                        valueBeforeLastValue = lastValue;
                        lastValue = currentValue;
                        currentValue = listeWerte.get(i);
                      
                        //Bedingung um den Typ aufsteigend zuzordnen
                        if (valueBeforeLastValue < lastValue && lastValue < currentValue == true){           
                           
                            //Erzeugen der Elemente/Objekte vom Typ aufsteigend
                            Trend trend1 = new Trend(valueBeforeLastValue, currentValue, "aufsteigend", "inital");

                            /* FRAGE: Mit jedem Durchlauf der übergeordneten for Schleife überschreibe ich hier aktuell mein Objekt trend1
                            Wie kann ich den Objektnamen dynamsich bilden?
                            Leider weiß ich nicht wie ich einen Objektnamen aus Variablen erzeuge kann :-(
                            Gibts dafür eine alternative Möglichkeit?
                            */
                        }
                       
                        //Bedingung um den Typ absteigend zuzordnen   
                        else if (valueBeforeLastValue > lastValue && lastValue > currentValue == true) { 
                              Trend trend2 = new Trend(valueBeforeLastValue, currentValue, "absteigend", "inital");
       
                        }
                     
                   }
                
       
                  }
              
           
             
                       
             
             
         }       
         

}

Code:
public class Trend {
    private int anfangsWert;
    private int letzterWert;
    private String type;
    private String valid;

     public Trend(int anfangsWert, int letzterWert, String type, String valid) {
        this.anfangsWert = anfangsWert;
        this.letzterWert = letzterWert;
        this.type = type;
        this.valid = valid;
        System.out.println("Gerade erstellt mit dem Anfangswert: " + anfangsWert + " Typ: "+ type + " Validity: " + valid);
        }

    public String getValid() {
        return valid;
    }

    public void setValid(String valid) {
        this.valid = valid;
    }

    public int getAnfangsWert() {
        return anfangsWert;
    }

    public int getLetzterWert() {
        return letzterWert;
    }

    public void setLetzterWert(int letzterWert) {
        this.letzterWert = letzterWert;
    }

    public void setTyp(String type) {
        this.type = type;
    }
}
 
K

kneitzel

Gast
Also bezüglich der "dynamischen Objektnamen": Du hast eine Applikation, und die muss mit den Daten etwas sinnvolles machen. Da erzeugt man nicht dynamisch weitere Variablen (So habe ich Dich jetzt verstanden). Und würde Dir auch nichts bringen, denn Du machst ja auch im Folgenden nichts mit den Daten (Was Dir der Compiler auch versucht hat, mitzuteilen).

Daher musst Du Dir als Entwickler überlegen, was mit den Daten weiter passieren soll. Typische Dinge sind da halt:
- Speichern für spätere Verarbeitung (Also z.B. in eine Datei oder im Speicher in einer Liste oder so ...)
- Direkt weiter geben, also sofort bearbeiten. Das ist, was ich mit Events meint, wobei das etwas .Net lastig ausgedrückt ist. Aber in Java wäre eine einfache Implementierung z.B. ein einfacher Consumer. Also könnte Deine Klasse Program eine Instanz vom Typ Consumer<Trend> haben und immer, wenn ein Trend erfolgreich erzeugt werden konnte, wird der Trend direkt an den Consumer weiter gegeben.

Die Idee ist halt nur, dass man die Abarbeitung in schöne kleine Happen aufteilt, von denen jeder für sich relativ einfach und unkompliziert ist und es nur minimale Abhängigkeiten zueinander gibt.
 

java_noob43

Mitglied
Also bezüglich der "dynamischen Objektnamen": Du hast eine Applikation, und die muss mit den Daten etwas sinnvolles machen. Da erzeugt man nicht dynamisch weitere Variablen (So habe ich Dich jetzt verstanden). Und würde Dir auch nichts bringen, denn Du machst ja auch im Folgenden nichts mit den Daten (Was Dir der Compiler auch versucht hat, mitzuteilen).

Daher musst Du Dir als Entwickler überlegen, was mit den Daten weiter passieren soll. Typische Dinge sind da halt:
- Speichern für spätere Verarbeitung (Also z.B. in eine Datei oder im Speicher in einer Liste oder so ...)
- Direkt weiter geben, also sofort bearbeiten. Das ist, was ich mit Events meint, wobei das etwas .Net lastig ausgedrückt ist. Aber in Java wäre eine einfache Implementierung z.B. ein einfacher Consumer. Also könnte Deine Klasse Program eine Instanz vom Typ Consumer<Trend> haben und immer, wenn ein Trend erfolgreich erzeugt werden konnte, wird der Trend direkt an den Consumer weiter gegeben.

Ich wollte keine Variablen bzw. Objekte zum Selbstzweck erstellen ;-).
Ich wollte auf die Trend1/2 Objekte mit zugreifen, um zu zeigen, was ich dann weiter damit machen möchte.
Allerdings funktioniert das leider nicht.
Bspw.:
Code:
System.out.println(trend1.getValid());
Der Compiler sag dazu "trend1 cannot be resolved"

Du hast natürlich recht die Compiler Meldung "The value of the local variable trend1/2 is not used" ist nur Symptom dessen, dass ich mit den Objeketen nichts mache und nicht Auslöser dafür, dass ich die Objekte nicht bspw. mit System.out.println(trend1.getValid()); nich ansprechen kann.

Kannst Du mir einen Typ geben, warum ich auf das Objekt trend1 in der Klasse Programm nach dessen Erstellung nicht zugreifen kann?
 
K

kneitzel

Gast
Das sind lokale Variablen und daher nur in dem Block der Variable gültig. Evtl. willst Du eine Instanzvariable nutzen oder so ....
 

java_noob43

Mitglied
Das sind lokale Variablen und daher nur in dem Block der Variable gültig. Evtl. willst Du eine Instanzvariable nutzen oder so ....

Welche lokale Variable meinst Du in dem Code oben?


Ich dachte nach dem gleichen Schema in einem anderen Code ein Objekt erzeugt zu haben und kann dort aus dem Main auf das Objekt car1 zugreifen.


Code:
public class Program {

    public static void main(String[] args) {

        Car bmw = new Car();
        Car car1 = new Car("grün", "VW", 130);
        bmw.setColour("pink");
        car1.drive(39);
        System.out.println(car1.getColour());
        System.out.println(bmw.getColour());
    }
   

}

Code:
public class Car {

    //Attribute/Eigenschaften
    private String colour; // Farbe
    private String brand; // Marke
    private int horsePower; // PS-Zahl
   
    public Car() {};
   
    public Car(String colour, String brand, int horsePower) {
    this.colour = colour;
    this.brand = brand;
    this.horsePower = horsePower;
    }
   
    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
       
        this.colour = colour;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getHorsePower() {
        return horsePower;
    }

    public void setHorsePower(int horsePower) {
        this.horsePower = horsePower;
    }

    //Methoden
    public void drive(int speed)  {
        System.out.println("Das Auto fährt..." + speed + "km/h");
    }
    public void drive()  {
        System.out.println("Das Auto fährt...");
    }
   
    }

In dem Code mit dem Objekt trend1 dachte ich alles prinzipiell gleich zu machen - aber offensichtlich ist da ein Unterschied den ich nicht sehe und nciht verstehe :-(
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Lokale Variablen werden in einem Codeblock deklariert und sind nur in diesem gültig. Wenn du einen Wert auch außerhalb der Methode nutzen willst, dann muss die Variable auch außerhalb deklariert werden.

die Variablen bmw und car1 sind also nur innerhalb main verfügbar.
 

java_noob43

Mitglied
mhm aus irgendeinem Grund nahm ich an Objekte existieren im Gegensatz zu Variablen (welche abhängig von der Sichtbarkeit und Ihrer deklaration sind) immer Global. Jetzt steh ich auf dem Schlauch wie ich dann die Objekterzeugung meiner trend1 und trend2 Objekte (innerhalb einer if bzw. if else Bedingung) außerhalb der Bedingung ansprechen kann?
 
K

kneitzel

Gast
Führen wir das einmal etwas aus:
Du hast in Java zwei Arten von Typen: Value Typen und Referenz Typen. Wenn wir dies visuell vorstellen wollen, dann ist das in etwa so wie: Zettel. Du kannst auf einen Zettel manche Dinge drauf schreiben. Das sind dann Value Typen. Aber manche Sachen passen da einfach nicht drauf. Wie kriegst du einen Hund auf den Zettel drauf? Da das nicht geht, gibt es die Referenzen. Das sind einfach Bindfäden. Wir binden also einen Bindfaden von dem Zettel bis zu dem Hund.

Nun hast Du aber noch den großen Aufräumer. Der rennt rum und schaut sich alles an. Und Alles, was keinen Bindfaden mehr zu einem Zettel hat, das räumt er weg. (Etwas stark vereinfacht. Ist etwas komplexer.)

Was sind dann lokale Variablen in z.B. einer Methode?
Die Methode weiß, was für Variablen Du in ihr nutzen willst und gibt dir dazu auch gleich die entsprechenden Zettel.
Sobald die Methode sich aber beendet, nimmt sie Die diese Zettel wieder weg! Und die Zettel sind auch fest mit der Methode verbunden. Du kannst diese also nicht weggeben.

Was Du aber machen kannst ist: Du kannst die Zettel nutzen für irgendwas. Also z.B. als Parameter für eine andere Methode. Aber die Zettel sind fest - die kannst Du nicht weggeben. Und die Methode hat an sich schon fertige Zettel dran gepappt. Also wenn Du einen zettel verwenden willst, wird da der Inhalt kopiert. Also wenn da auf dem Zettel in der Methode 5 steht, dann schreibt man auf den angepappten Zettel auch die 5. Wenn an einem Zettel ein Bindfaden war, dann spannt man einen weiteren Bindfaden - halt vom anderen Zettel hin zu z.B. dem Hund.

Also was machst Du da derzeit?
Du hast Zwei Zettel trend1 und trend2. Du erzeugst Auch Objekte und verbindest die mit diesen Zetteln. Aber dann ist die methode vorbei und die Zettel sind weg. Und dann kommt früher oder später (Wann genau ist nicht definiert) der Aufräumer und dann schmeißt er die beiden erzeugten Objekte auch weg.

Was Du also machen kannst, ist: Du nutzt Zettel, die irgendwo fest sind, was Du hast. Also z.B. Instanzvariablen. Wenn Du da dann solche Fäden spannst, dann sieht der Aufräumer die und schmeißt die auch nicht weg.

Und du kennst diese Zettel und kannst auf diese zugreifen.

Also ja: Die Objekte existieren "global". Aber Du brauchst immer eine Variable, um auf diese zuzugreifen.
 

java_noob43

Mitglied
Danke für die ausführliche Erklärung.
Leider verstehe ich den Kontext zu den Instanzvariablen nicht.

bspw.:

Code:
public class Trend {
    public int anfangsWert;
    public int letzterWert;
    public String type;
    public String valid;

     public  Trend(int anfangsWert, int letzterWert, String type, String valid) {
        this.anfangsWert = anfangsWert;
        this.letzterWert = letzterWert;
        this.type = type;
        this.valid = valid;
        System.out.println("Gerade erstellt mit dem Anfangswert: " + anfangsWert + " Typ: "+ type + " Validity: " + valid);
        }
}

Ich habe ein bischen rum gelsen und hatte das Verständnis gewonnen, dass die Instanzvariablen sind:
Code:
    public int anfangsWert;
    public int letzterWert;
    public String type;
    public String valid;

Um in Deinem Beispiel zu bleiben wäre das ja ein konkreter Zettel. Wie kann ich darin den Zustand von Objekten speichern, also bspw. von trend1 und trend2?
 
K

kneitzel

Gast
Ja genau. Das sind Instanzvariablen. Also wenn man in dem Beispiel mit denn Zetteln bleibt, dann hat man da zwei Zettel auf denen man eine Zahl schreiben kann und zwei Zettel, die einen Bindfaden hin zu einem String Objekt aufnehmen können.
Das ist also, was ein Objekt vom Typ "Trend" ausmacht.

Aber es ging ja nicht um die Klasse Trend, sondern darum, wo Du diese genutzt hast. Das war etwas, das wie folgt aussah:
Java:
public class SomeClass {
  public void someMethod() {
    // Lokale Variablen ...
    Trend trend1;
    Trend trend1;
    
    // Die Variablen sind nur hier in der Methode gültig!
  }
}

Das könnte man zu etwas wie dem machen:
Java:
public class SomeClass {
  // Instanz - Variablen ...
  Trend trend1;
  Trend trend1;

  public void someMethod() {
    
  }
}

Jetzt sind trend1 und trend2 Instanzvariablen und somit innerhalb jeder Instanz verfügbar. Also in einer Methode kannst Du trend1 und trend2 Werte zuweisen um diese dann in einer anderen Methode zu verwenden.
 

java_noob43

Mitglied


Danke das hat sehr geholfen - im Nachhinein logisch.

Ich habe weiter recherchiert und habe den Eindruck, dass ich men Problem Objekte zur Laufzeit erzeugen zu wollen mit einer Hashmap lösen könnte.

Ich habe mich mit der Hashmap beschäftigt und einerseits versucht Objekte vom Typ Auto zur Laufzeit zu erzeugen (klappt) und gezielt aufzurufen (klappt nicht).

Desweiteren habe ich versucht Code-Beispiele nachzuvollziehen (klappt nicht). Insgesamt habe ich also den Eindruck ich habe die hashmap leider noch nicht richtig verstanden zu haben :-(.

Könntest Du mir noch mal ein paar Denkanstöße geben?

Code:
import java.util.ArrayList;
import java.util.HashMap;

public class Programm {

public static void main(String[] args) {

      
      ArrayList<Integer> listeWerte = new ArrayList<Integer>();
      listeWerte.add(11);
      listeWerte.add( 13);
      listeWerte.add( 14);
      listeWerte.add(9);
      listeWerte.add(7);
      listeWerte.add( 6);
   
      for (int i =0; i < listeWerte.size(); i++)
      {
        
      if (listeWerte.get(i) !=13) {
      HashMap<String, Auto> trend = new HashMap<String, Auto>();
      trend.put(Integer.toString(i),new Auto());
      System.out.println("hashmap erweitert " + i);
    /*  trend.get(Integer.toString(1)).setColour("schwarz");
      System.out.println(trend.get(i).getColour());
      -> Ich verstehe leider meinen Denkfehler an der auskommentierten Stelle nicht.
      Wie kann ich die Einträge der Hashmap hier nach einzeln ansprechen?
      *
      */
      }
      }
    
      HashMap<Integer, String> hash_map = new HashMap<Integer, String>();
    
      // Mapping string values to int keys
      hash_map.put(10, "Geeks");
      hash_map.put(15, "4");
      hash_map.put(20, "Geeks");
      hash_map.put(25, "Welcomes");
      hash_map.put(30, "You");

      // Displaying the HashMap
      System.out.println("");
      System.out.println("Initial Mappings are: " + hash_map);
      System.out.println("Hier verstehe ich nicht warum die Ausgabereihenfolge nicht [10=Geeks, 15=4, 20=Geeks, 25=Welcomes, 30=You] ist.");
    
    
      // Using keySet() to get the set view of keys
      System.out.println("");
      System.out.println("The set is: " + hash_map.keySet());
      System.out.println("Hier verstehe ich nicht warum die Ausgabereihenfolge nicht [10, 15, 20, 25, 30] ist.");


}
}

Code:
public class Auto {

    //Attribute/Eigenschaften
    private String colour; // Farbe
    private String brand; // Marke
    private int horsePower; // PS-Zahl
   
    public Auto() {};
   
    public Auto(String colour, String brand, int horsePower) {
    this.colour = colour;
    this.brand = brand;
    this.horsePower = horsePower;
    }
   
    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }
}
 
K

kneitzel

Gast
HashMap ist gut, wenn Du Values einem Key zuordnen willst. Aber hast Du denn wirklich einen Key? Oder hast nur eine Abfolge von Werten, so dass da eine List (z.B. ArrayList) besser geeignet wäre?

Und wenn Du eine neue Instanz von Auto erzeugst, dann ist es ok, diese abzuspeichern. Aber um dann noch Attribute zu ändern, würde ich diese nicht ständig aus der HashMap heraus holen. Du hast sie ja eben erst erzeugt...

Also typische Szenarien sind da eigentlich immer:
- Instanz in lokaler Variable erzeugen
- Instanz aufbereiten zur Speicherung (Also da alles zu setzen, was Du setzen willst)
- Instanz abspeichern.
Man kann hier natürlich teilweise die Reihenfolge verändern. Also so wie Du es gemacht hast: erst speichern und dann etwas verändern. Das kann funktionieren aber es ist vom Vorgehen her unlogisch und funktioniert auch nur, wenn
- die Referenz gesichert wurde
- der hashCode keine Rolle beim (wieder-) finden spielt.

Ein Beispiel wo es z.B. nicht funktioniert wäre ein speichern in eine Datei.

Und statt int -> String wäre evtl int -> Integer besser, so dies wirklich der Key ist. Dann muss da weniger berechnet werden, denn den Hashcode hast Du ja direkt....

Und Denkfehler ist einfach: Du hast da den Wert i genommen als Key. War den i wirklich 1? Die Schleife fängt ja z.B. bei 0 an....
 

java_noob43

Mitglied
HashMap ist gut, wenn Du Values einem Key zuordnen willst. Aber hast Du denn wirklich einen Key? Oder hast nur eine Abfolge von Werten, so dass da eine List (z.B. ArrayList) besser geeignet wäre?
Mein Problem (war) die zur Laufzeit generierten Objekte zu finden.
Ich hatte mir das so vorgestellt, dass ich den key aus einer Variable erstelle und einfach solange um eins inkrementiere wie Objekte zur Laufzeit des Programms erstellt werden - ich füge dann also jedes Objekt mit einem inkrementierendem Key der hashmap hinzu.
Dann kann ich in anderen Schritten des Programms die Hashmap nach den zur Laufzeit erstellten Objekten durchsuchen und in diesen Objekten dann die Eigenschaften verändern.

Mir dient die Hashmap also nur dazu eine Referenzliste über alle zur Laufzeit erstellten Objekte von bestimmten Klassen zu erhalten.

Ich habe dafür jetzt eine Lösung gefunden :)

Code:
import java.util.ArrayList;
import java.util.HashMap;

public class Programm {

public static void main(String[] args) {

        
      ArrayList<Integer> listeWerte = new ArrayList<Integer>();
      listeWerte.add(11);
      listeWerte.add( 13);
      listeWerte.add( 14);

     
      HashMap<Integer, Auto> trend = new HashMap<Integer, Auto>();
      for (int i =0; i < listeWerte.size(); i++)
          {
          trend.put(i,new Auto());
          System.out.println("hashmap erweitert " + i);
          }
      
      Auto obj = trend.get(1);
      System.out.println(obj.getColour());
      obj.setColour("schwarz");
      System.out.println(obj.getColour());
      
      System.out.println("_________________________");
    
      
      
      
      HashMap<Integer, String> hash_map = new HashMap<Integer, String>(); 
      
      // Mapping string values to int keys 
      hash_map.put(10, "Geeks"); 
      hash_map.put(15, "4"); 
      hash_map.put(20, "Geeks"); 
      hash_map.put(25, "Welcomes"); 
      hash_map.put(30, "You"); 

      // Displaying the HashMap 
      System.out.println("");
      System.out.println("Initial Mappings are: " + hash_map); 
      System.out.println("Frage 1: Hier verstehe ich nicht warum die Ausgabereihenfolge {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4} ist und nicht 10=Geeks, 15=4, 20=Geeks, 25=Welcomes, 30=You ist.");
      
      
      // Using keySet() to get the set view of keys 
      System.out.println(""); 
      System.out.println("The set is: " + hash_map.keySet()); 
      System.out.println("Frage 2: Hier verstehe ich nicht warum die Ausgabereihenfolge [20, 25, 10, 30, 15] ist und nicht [10, 15, 20, 25, 30] ist.");
}

}
An dem Code versteh ich zum hash_map und hash_map.keySet() jetzt leider folgendes nicht:
Frage 1: Ich verstehe nicht warum die Ausgabereihenfolge {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4} ist und nicht 10=Geeks, 15=4, 20=Geeks, 25=Welcomes, 30=You ist.
Frage 2: Ich verstehe nicht warum die Ausgabereihenfolge [20, 25, 10, 30, 15] ist und nicht [10, 15, 20, 25, 30] ist.");
 
K

kneitzel

Gast
Mein Problem (war) die zur Laufzeit generierten Objekte zu finden.
Ich hatte mir das so vorgestellt, dass ich den key aus einer Variable erstelle und einfach solange um eins inkrementiere wie Objekte zur Laufzeit des Programms erstellt werden - ich füge dann also jedes Objekt mit einem inkrementierendem Key der hashmap hinzu.
Dann kann ich in anderen Schritten des Programms die Hashmap nach den zur Laufzeit erstellten Objekten durchsuchen und in diesen Objekten dann die Eigenschaften verändern.

Mir dient die Hashmap also nur dazu eine Referenzliste über alle zur Laufzeit erstellten Objekte von bestimmten Klassen zu erhalten.

Also hast Du keinen Key und generierst Dir künstlich irgendwas ... Dann nimm doch eine ArrayList - da hast Du den Zugriff über den Index des hinzugefügten Elements.

Ich habe dafür jetzt eine Lösung gefunden :)

Code:
import java.util.ArrayList;
import java.util.HashMap;

public class Programm {

public static void main(String[] args) {

       
      ArrayList<Integer> listeWerte = new ArrayList<Integer>();
      listeWerte.add(11);
      listeWerte.add( 13);
      listeWerte.add( 14);

    
      HashMap<Integer, Auto> trend = new HashMap<Integer, Auto>();
      for (int i =0; i < listeWerte.size(); i++)
          {
          trend.put(i,new Auto());
          System.out.println("hashmap erweitert " + i);
          }
     
      Auto obj = trend.get(1);
      System.out.println(obj.getColour());
      obj.setColour("schwarz");
      System.out.println(obj.getColour());
     
      System.out.println("_________________________");
   
     
     
     
      HashMap<Integer, String> hash_map = new HashMap<Integer, String>();
     
      // Mapping string values to int keys
      hash_map.put(10, "Geeks");
      hash_map.put(15, "4");
      hash_map.put(20, "Geeks");
      hash_map.put(25, "Welcomes");
      hash_map.put(30, "You");

      // Displaying the HashMap
      System.out.println("");
      System.out.println("Initial Mappings are: " + hash_map);
      System.out.println("Frage 1: Hier verstehe ich nicht warum die Ausgabereihenfolge {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4} ist und nicht 10=Geeks, 15=4, 20=Geeks, 25=Welcomes, 30=You ist.");
     
     
      // Using keySet() to get the set view of keys
      System.out.println("");
      System.out.println("The set is: " + hash_map.keySet());
      System.out.println("Frage 2: Hier verstehe ich nicht warum die Ausgabereihenfolge [20, 25, 10, 30, 15] ist und nicht [10, 15, 20, 25, 30] ist.");
}

}
An dem Code versteh ich zum hash_map und hash_map.keySet() jetzt leider folgendes nicht:
Frage 1: Ich verstehe nicht warum die Ausgabereihenfolge {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4} ist und nicht 10=Geeks, 15=4, 20=Geeks, 25=Welcomes, 30=You ist.
Frage 2: Ich verstehe nicht warum die Ausgabereihenfolge [20, 25, 10, 30, 15] ist und nicht [10, 15, 20, 25, 30] ist.");

Die Keys sind ein Set, also eine Menge. Da ist keine Reihenfolge. Wenn Du Elemente in einer Reihenfolge hast, dann verwende entsprechende Datentypen.
 

java_noob43

Mitglied
Also hast Du keinen Key und generierst Dir künstlich irgendwas ... Dann nimm doch eine ArrayList - da hast Du den Zugriff über den Index des hinzugefügten Elements.
Die Keys sind ein Set, also eine Menge. Da ist keine Reihenfolge. Wenn Du Elemente in einer Reihenfolge hast, dann verwende entsprechende Datentypen.


Eigentlich haben die Daten keine Reihenfolge. Ich konnte bloß das Beispiel nicht nachvollziehen. Nachdem Du den Mengenbegriff nochmal in den Vordegrund geschoben hast macht das natürlich Sinn. Vielen Dank!


Da ich die Objekte nur ablegen muss und gedenke anschließend durch die kompletten Werte mit einer Schleife zu laufen, um je Objekt ein Objektattribut aufzurfen und zu vergleichen frage ich mich ob die Hashmap oder die arraylist geeigneter ist. Reihenfolge hilft mir aufgrund des Dateninhalts und weiteren Programmablaufs nicht.

Die Schleife zum Aufruf der Objekte und der Werte-Vergleich wird allerdings in verschiedenen Speilarten sehr häufig vorkommen und es sind ca. 20.000 Elemente in der Liste. Ich stelle mir daher die Frage ob es performanter ist eine Arraylist zu nehmen oder eine Hashmap (in dr ich den key selber hochzählen würde)?
 
K

kneitzel

Gast
Eine Map besteht aus Key/Value Paaren ... scheinst Du nicht zu haben....
Dann gibt es die Liste - da kann man Dinge rein stopfen und sie behalten die Reihenfolge ...
Dann gibt es Sets - da ist die Reihenfolge egal.

Wenn die Reihenfolge egal ist, dann würde ich mich mal bei den Sets umschauen. Wobei es ja auch nicht schadet, wenn die Reihenfolge weiter sicher gestellt ist, daher kannst Du auch bei der List bleiben.
 

java_noob43

Mitglied
Danke.

Jetzt komme ich endlich gut voran.
Habt ihr noch einen Tipp wie man einem Objekt, dass eine arraylist als attribut hat, einzeln werte in die arrayliste anfügen kann?

Code:
obj.setListeBreakValues(1.2);

schmeißt der Compiler
"The method setListeBreakValues(ArrayList<Float>) in the type Trend is not applicable for the arguments (Float)"

Setter in der Klasse des Objekts:
Code:
    public void setListeBreakValues(ArrayList<Float> listeBreakValues) {
        this.listeBreakValues = listeBreakValues;
    }


In der Klasse, welche das Objekt erstellt habe ich die Liste wie folgt deklariert:
Code:
private ArrayList<Float> listeTouchValues = new ArrayList<Float>();


Offensichtlich passt der setter nicht zur Liste.
Ich möchte aber eigentlich nicht einen Wert in der Arrayliste überschreiben, sondern dort mehrere hinzufügen.
Wie kann man da ordentlich hinkommen?
Ich hatte die Hoffnung, dass ich add nehemn kann, aber das bietet mir die Entwicklungsumgebung nicht mal an :-(
 
K

kneitzel

Gast
Statt einem Setter kannst du eine add Methode schreiben, die dann das Element hinzu fügt.
 

White_Fox

Top Contributor
Ja, das nennt sich Reflexion.


Es ist aber mit Vorsicht zu genießen und durchaus etwas umständlich. Ich halte es für sehr wahrscheinlich, daß es für dein Problem eine bessere Lösung gibt.
 

java_noob43

Mitglied
Ok. Danke. Ich seh schon mehr Kontext würde helfen.

Also ich habe eine Methode die aus einer Array-Liste Objekte nimmt und damit etwas macht.
Den im wesentlichen gleichen Code der Methode muss ich auch auf die Objekte des gleichen Typs in diversen anderen Array-Listen anwenden.
Mit künftiger Weiterentwicklung des Programmes werden weitere Array-Listen die von der gleichen Methode zu verarbeiten sind zu behandeln sein.

Jetzt möchte ich natürlich nicht die Methode x-mal kopieren und darin jeweils nur hart die unterschiedlichen Array-listen vedrahten und ein paar andere Sachen ändern die Abhängig von der Array-list dsind und mich bei jeder Arraylisten-Erweiterung wieder dadurchquälen alle Abhängigkeiten richtig zu ändern und aufwändig zu testen.

Statt dessen habe ich mir überlegt an einer zentralen Stelle zu pflegen, welche Array-Listen-Namen es gibt - und die anderen Sachen (die anderen Parameter lass ich der einfachheit halb mal weg, da wenn ich die Lösung für das eine Problem kenn dieselbe Lösung auch darauf anwendbar sein wird).
Ich möchte die Methode dann so ändern, dass ich diese ohne Angabe der Array-Liste aufrufe kann und innerhalb der Methode dann in einer Schleife Array-Listen-Namen zuweise, mit dennen die Methode dann ihren Code ausführt.

Der fehlende Teil dazu ist gerade, wie kann ich eine Variable mit einem Befehl verketten.

Beispiel hart verdrahtet als pseude code:
Code:
ArrayList<Extreme> listOfHighExtemeValues= new ArrayList<Extreme>();
ArrayList<Extreme> listOfHLowExtemeValues= new ArrayList<Extreme>();

for (int i = 0, i < listOfHighExtemeValues.size(), i++)
{
listOfHighExtemeValues.get(i).AndereMethodeaufrufen();
}


for (int i = 0, i < listOfHLowExtemeValues.size(), i++)
{
listOfHLowExtemeValues.get(i).AndereMethodeaufrufen();
}

// die for-Schleife siehe oben müsste dann für jede weitere Liste vom Typ Extreme kopiert und angepasst werden

Vorstellung generischer pseudocode:
Code:
ArrayList<Extreme> listOfHighExtemeValues= new ArrayList<Extreme>();
ArrayList<Extreme> listOfHLowExtemeValues= new ArrayList<Extreme>();

//folgendes würde ich dann an zentraler Stelle einmalig pflegen
ExtremValueNames.add("listOfHighExtemeValues");
ExtremValueNames.add("listOfHLowExtemeValues");

//Hier dann schön generisch
for (int index = 0; index < ExtremValueNames.size(); index ++)
{
String c = ExtremValueNames.get(index);

for (int i  = 0, i < c.size(), i++)
{
c.get(i).AndereMethodeaufrufen();
}
}

Oder gibts da ne bessere Lösung für als, das was ich mir unter generischer Pseudocode skizziert habe?
 
K

kneitzel

Gast
Wenn nur die Array Liste unterschiedlich ist, dann gib die als Parameter an die Methode.
Wenn eine Methode unterschiedlich ist (z.B. unterschiedliche Getter für einen Wert), dann kannst du das auch als Parameter übergeben....

Aber ich verstehe derzeit nicht, was das eigentliche Problem ist. Evtl. kannst du ja mal zwei Methoden/Klassen zeigen ....

Wenn es um ein Verhalten in unterschiedlichen Klassen geht, dann könnte man das auch in einer eigenen Klasse Kapseln. Das ginge dann etwas Richtung Strategy Pattern, das auch ein Verhalten kapselt (auch wenn es hier etwas anders gelagert ist, da es nicht nur um ein Verhalten geht so wie ich es verstanden habe ...)
 

java_noob43

Mitglied
Wenn nur die Array Liste unterschiedlich ist, dann gib die als Parameter an die Methode.
Die Listen an die Methode
Code:
 AndereMethodeaufrufen()
zu übergeben habe ich mir auch gedacht - siehe Beispiel. Ich möchte allerdings erreichen, dass ich nicht für jede neue Liste die ich dem Programm hinzufüge einen seperaten Aufruf der Methode mit der neu hinzugefügten Liste schreiben muss.
Code:
ArrayList<Extreme> listOfHighExtemeValues= new ArrayList<Extreme>();
ArrayList<Extreme> listOfHLowExtemeValues= new ArrayList<Extreme>();

//folgendes würde ich dann an zentraler Stelle einmalig pflegen
ExtremValueNames.add("listOfHighExtemeValues");
ExtremValueNames.add("listOfHLowExtemeValues");

//Hier dann schön generisch
for (int index = 0; index < ExtremValueNames.size(); index ++)
{
String c = ExtremValueNames.get(index);

for (int i  = 0, i < c.size(), i++)
{
c.get(i).AndereMethodeaufrufen();
}
}


Statt dessen möchte ich, dass das Programm die Methode solange aufruft wie ich in einer Liste der Listennamen
Code:
 ExtremValueNames
, Listennamen angegeben habe. Dazu habe ich mir soetwas wie oben überlegt, also der Variable c eine Listennamen aus der Liste der Listennamen zu übergeben und mi diesem dann die Methode aufzurufen. Es harkt jetzt daran, dass ich nicht weiß wie ich den der Variable c zugewiesenen Listennamen mit ".get(i).AndereMethodeaufrufen();" so verknüpfen kann, dass der Compiler
Code:
 c.get(i).AndereMethodeaufrufen();
als
Code:
  ExtremValueNames.get(i).AndereMethodeaufrufen()
interpretiert.


Aber ich verstehe derzeit nicht, was das eigentliche Problem ist. Evtl. kannst du ja mal zwei Methoden/Klassen zeigen ....

Die Methode
Code:
 AndereMethodeaufrufen
verändert das Objekt das die Methode aufruft.
Im Wesentlichen ist die Methode
Code:
 AndereMethodeaufrufen
eine Mastemethode, welche diverse Vergleiche und Operationen durchführt und abhängig von den Ergebnissen unterschiedliche Verzweigungen durchläuft in dennen sie wiederum andere Methoden aufruft.


Hilft das?
 

mihe7

Top Contributor
Ich möchte allerdings erreichen, dass ich nicht für jede neue Liste die ich dem Programm hinzufüge einen seperaten Aufruf der Methode mit der neu hinzugefügten Liste schreiben muss.
Statt eines Methodenaufrufs an der Stelle, die Du sowieso gerade änderst, willst Du also lieber die Liste dem Code einer anderen Methode, die sich vermutlich auch noch in einer anderen Klasse befindet, hinzufügen? Das ist so ziemlich das schlechteste, was man überhaupt machen kann.

Einmal abgesehen davon, dass Du den Code an verschiedenen Stellen ändern musst, was dazu führt, dass die jeweiligen Klassen natürlich auch kompiliert werden müssen, wird Deine "zentrale Methode" abhängig von jeder Liste (und damit Klasse, die diese enthält).

Wenn du mal konkret schreiben würdest, worum es eigentlich geht, dann könnte man auch konkret sagen, wie man es anders lösen könnte. Allgemein kann ich Dir nur sagen, dass Du so etwas über verschiedene Interfaces voneinander entkoppeln kannst (ob das jetzt mittels List, Map, Supplier, Kombinationen daraus oder speziellen Schnittstellen läuft, kommt eben auf Deinen konkreten Fall an).
 

White_Fox

Top Contributor
Ansonsten wäre noch eine Möglichkeit, daß du anstatt von Array Datenobjekte einführst, die die Daten enthalten und intern bearbeiten.

Könnte es zufällig sein, daß deine Klassen zu viele Aufgaben auf einmal stemmen müssen?
 

java_noob43

Mitglied
ich überarbeite den code gerade. Dabei stoße ich darauf, dass ich in einem Objekt einer String Variable einen Wert zugewiesen habe, wenn ich den auslsen möchte kommt aber null zurück.

Im Debugmodus wird mir zu der Objekt Variable angezeigt:

type = "Higher High" (id = 60)
coder=0
hash=0
hashlsZero= false
value= (id=63)
[0] = 72
[1] = 105
[2] 103
[3] 104
[4] 101
[5] 114
[6] 32
[7] 72
[8] 105
[9] 103
[10] 104


Warum bekomme ich bei zugriff auf das object mit object.getType() nicht Higher High sondern null zurück?
 

White_Fox

Top Contributor
Ehrlich gesagt kann ich dir nicht folgen.

An deiner Stelle würde ich den Rechner ausmachen und mir Papier und Bleistift nehmen und das Problem analysieren. Schreibe auf, was am Ende rauskommen soll. Dann schreibe auf, warum was bisher nicht geklappt hat. Identifiziere die Teile, die kompliziert sind. Und dann überleg dir, wie du das vereinfachen kannst.

Ja, so mache ich das tatsächlich, wenn ich ein komplexes Problem habe: Rechner aus, Schreiberei auf die althergebrachte Art.
Nein, ich stehe nicht kurz vor der Rente, im Gegenteil, das ist bei mir noch sehr lange hin.

Komplizierte Lösungen sind eigentlich immer schlecht. Die genialsten Lösungen sind diejenigen, deren Einfachheit das Publikum vor Verblüffung verstummen läßt.
 

Neue Themen


Oben