GOTO (aus Digitaluhr, Hilfe !)

Blender3D

Top Contributor
Diese ganzen ifs machen mich ganz wuschig. :) Mit Hilfe von Java 9 VarHandles und Lambdas kann man das noch etwas abstrahieren. Naja... nur, dass man hierfür Instanzvariablen benötigt... aber egal:
Nette Variante mit Nachteilen:
a) Unübersichtlicher Code.
b) Abhängigkeit von Java 9

Die vielen Ifs kann man auch mittels einer Schleife kaschieren.
Java:
public class TimeTicker {
    private int[] max = { 10, 60, 60, 24 };
    private int[] time = { 0, 0, 0, 0 };
    public final static int PART_OF_SECOND = 0;
    public final static int SECOND = 1;
    public final static int MINUTE = 2;
    public final static int HOUR = 3;

    private int countUpValue(int value, int max) {
        value++;
        return (value >= max) ? 0 : value;
    }

    public long getExpectedDelayInMilliSeconds() {
        return 1000l / max[PART_OF_SECOND];
    }

    public void tick() {
        for (int i = 0; i < time.length; i++) {
            time[i] = countUpValue(time[i], max[i]);
            if (time[i] != 0)
                break;
        }
    }

    @Override
    public String toString() {
        return String.format("%d:%02d:%02d,%d", time[HOUR], time[MINUTE], time[SECOND], time[PART_OF_SECOND]);
    }

}
Java:
public class start {
    public static void main(String[] args) {
        TimeTicker time = new TimeTicker();
        while (true) {
            time.tick();
            try {
                Thread.sleep(time.getExpectedDelayInMilliSeconds());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(time);
        }
    }
}
 
X

Xyz1

Gast
@Blender3D Etwas unschön:
1. break
2. magische Konstanten
3. nicht an der aktuellen Zeit angelegt
4. feste Wartezeit von 100ms, dadurch ist der TimeTicker ungenau
5. final vergessen
6. final an unüblicher Stelle
7. Logik in der main
8. zu klein gewählter try-catch
9. nach 24 Stunden fliegt Dir alles um die Ohren :oops:

Java:
public class Uhr extends Thread {
    private final int[] max = { 10, 60, 60, 24 };
    private final int[] time = { 0, 0, 0, 0 };
    private static final int expectedDelayInMilliSeconds = 100;
    public static final int PART_OF_SECOND = 0;
    public static final int SECOND = 1;
    public static final int MINUTE = 2;
    public static final int HOUR = 3;

    private int countUpValue(int value, int max) {
        value++;
        return (value >= max) ? 0 : value;
    }

    public long getExpectedDelayInMilliSeconds() {
        return expectedDelayInMilliSeconds;
    }

    public void tick() {
        int time;
        int i = 0;
        do {
            time = (this.time[i] = countUpValue(this.time[i], max[i]));
            i++;
        } while (time == 0 && i < max.length);
    }

    @Override
    public String toString() {
        return String.format("%d:%02d:%02d,%d", time[HOUR], time[MINUTE], time[SECOND], time[PART_OF_SECOND]);
    }

    public static void main(String[] args) {
        try {
            Uhr time = new Uhr();
            while (true) {
                time.tick();
                Thread.sleep(time.getExpectedDelayInMilliSeconds());
                System.out.println(time);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 

Blender3D

Top Contributor
1. break
2. magische Konstanten
3. nicht an der aktuellen Zeit angelegt
4. feste Wartezeit von 100ms, dadurch ist der TimeTicker ungenau
5. final vergessen
6. final an unüblicher Stelle
7. Logik in der main
8. zu klein gewählter try-catch
9. nach 24 Stunden fliegt Dir alles um die Ohren :oops:
1.
Java:
public void tick() {
        for (int i = 0; i < time.length; i++) {
            time[i] = countUpValue(time[i], max[i]);
            if (time[i] != 0)
                break;
        }
    }
Durch break wird hier jedes 10 mal eine 2te, jedes 600 mal eine 3te und jedes 36000te mal eine if Bedingung abgefragt
Die Funktion hat die Aufgabe den Zeit Zähler zu erhöhen. Die Abbruchbedingung der Schleife ist hier gut lesbar in dem 4zeiligen Code formuliert. Deine "verbesserte Variante" mit der while Schleife reduziert die Lesbarkeit anstatt sie zu verbessern.
2) Die Konstanten sind nicht magisch sie dienen der Lesbarkeit und können später für eine Getterfunktion der einzelnen Zählerstände benutzt werden. Genauso macht es die Klasse Calendar, die Du in Deiner, nicht der Aufgabenstellung entsprechenden Lösung, verwendest.
3) 4) Das ist nicht die Aufgabe des Timetickers.
5) 6) ein private Array final zu machen hat keinen Effekt in diesem Zusammenhang. Konstant ist da nur die Referenz des auf das Array selbst. Die Konstanten sind natürlich static ,final und public. Sie werden z.B. bei einer zukünftigen getter Funktion von außen benutzt.
7) Die Logik von Timeticker ist nicht in der main. Was Du meinst ist die Testklasse, um den Timeticker zu testen. Wenn es später einmal um Genauigkeit geht wird das von einer Klasse z.B. Uhr gemacht, die diese Aufgabe erfüllt. Deshalb besitzt der TimeTicker auch die Methode
Java:
 public long getExpectedDelayInMilliSeconds() {
        return 1000l / max[PART_OF_SECOND];
    }
Diese gibt keine Konstante zurück, um es zu ermöglichen mit einer setter Funktion die Auflösung des TimeTicker einzustellen.
8) Das Testprogramm macht genau das was es soll.
9) Die Uhr beginnt wieder bei 00:00:00,0
 
X

Xyz1

Gast
Durch break wird hier jedes 10 mal eine 2te, jedes 600 mal eine 3te und jedes 36000te mal eine if Bedingung abgefragt
Die Funktion hat die Aufgabe den Zeit Zähler zu erhöhen. Die Abbruchbedingung der Schleife ist hier gut lesbar in dem 4zeiligen Code formuliert. Deine "verbesserte Variante" mit der while Schleife reduziert die Lesbarkeit anstatt sie zu verbessern.
Das sieht Dijkstra anders. ;)

2) Die Konstanten sind nicht magisch sie dienen der Lesbarkeit und können später für eine Getterfunktion der einzelnen Zählerstände benutzt werden.
In der einen Methode hast du eine magische Konstante...

3) 4) Das ist nicht die Aufgabe des Timetickers.
Das stimmt, wenn man die Aufgabe des TEs so auslegen möchte.

5) 6) ein private Array final zu machen hat keinen Effekt in diesem Zusammenhang
Aber in einem Späteren. ;)

Die Logik von Timeticker ist nicht in der main. Was Du meinst ist die Testklasse, um den Timeticker zu testen. Wenn es später einmal um Genauigkeit geht wird das von einer Klasse z.B. Uhr gemacht, die diese Aufgabe erfüllt
Du hast also nur die halbe Aufgabe gelöst. ;)

8) Das Testprogramm macht genau das was es soll
Ja, solange keine Fehler auftreten...

9) Die Uhr beginnt wieder bei 00:00:00,0
Stimmt, das habe ich übersehen. :(

--

Jedenfalls sollte es doch jetzt viiiele Lösungsmöglichkeiten für den TE geben. :)
 

Blender3D

Top Contributor
Das sieht Dijkstra anders
Mit welchen Argumenten ? lol Bitte die Quelle mit Kontext angeben, bevor Du solche Dinge in den Raum stellst.

Java:
 public void tick() { // 4 Zeilen Code
        for (int i = 0; i < time.length; i++) { // Bedingung 1 = Länge des Arrays
            time[i] = countUpValue(time[i], max[i]);
            if (time[i] != 0) // Bedingung 2 = Überlauf des jeweiligen Counters
                break;
        }
    }
versus
Java:
public void tick() { // 6 Zeilen Code
        int time; // unnötige Variable
        int i = 0;
        do {
            time = (this.time[i] = countUpValue(this.time[i], max[i]));
            i++;
        } while (time == 0 && i < max.length); // verknüpfte Bedingungen erschwert die Lesbarkeit
    }
In der einen Methode hast du eine magische Konstante...
Falls Du diese Funktion meinst,
Java:
   public long getExpectedDelayInMilliSeconds() {
        return 1000l / max[PART_OF_SECOND];
    }
dann übersetze erst einmal den Methodennamen und Dir wird klar woher die Konstante 1000l kommt. Ob diese Konstante magische ist hängt dann nur mehr von den Fähigkeiten einen Code zu lesen ab. ;)
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Ähm, das break mit einem GOTO zu vergleichen ist gewagt. Ebenso bei aktuellen Clean Code Fragen einen Pionier zu bringen, dessen aktive Zeit gut 2 Jahrzehnte vorbei ist, halte ich ebenso für gewagt.

Daher ist die Frage nach einer Begründung doch durchaus angebracht. Und so Kritik sollte halt begründet werden können. (Und aus aktuellem Anlass: Etwas dann einfach als "Bullshit" zu bezeichnen ist keine Begründung!)
 

Blender3D

Top Contributor
Ich kann das lesen, allerdings erschwert...

Zum Versus... Das stimmt, eine Variable wäre überflüssig, spart aber einen Array Zugriff und ist leichter zu lesen...

Zu Dijkstra: https://en.wikipedia.org/wiki/Considered_harmful . Genaue Belege habe ich aber nich.

Nimm meine Kritikpunkte doch mal als sehr sinnvoll an. ;)
Ein Arrayzugriff passiert direkt. (Basics). Wo wird hier irgend etwas gespart? Und leichter zu lesen? --> time = this.time[] . Hier muss ich zwei Variablen betrachten anstatt einer.
Der Link zu Dijkstra ist mir bekannt. Du solltest diesen aber lesen, da geht es um GOTO also einen Sprung. Das hat mit break gar nichts zu tun. Der Unterschied ist Dir aber scheinbar nicht geläufig. Also ich bin gerne bereit begründete Kritikpunkte anzunehmen, weil man sich nur mit Kritikfähigkeit weiterentwickelt. Wobei hier die Betonung auf begründet liegt. Ich kann in Deiner Argumentation keinen wirklich guten Grund für eine Codeänderung finden außer ich möchte diesen 'verschlechtbessern'.
 
K

kneitzel

Gast
Gewagt ist auch ein geflügeltes Wort... etwas wischi waschi... Du weißt aber schon, das Dijkstra seit geraumer Zeit nicht mehr unter den Lebenden weilt?
Schön das Thema gewechselt. 99 ist er in Ruhestand gegangen (Also aktive Zeit seid 2 Jahrzehnten vorüber - so wie ich geschrieben habe. Seine großen Veröffentlichungen waren sogar deutlich vor 99!), 2002 gestorben (Was aber in diesem Zusammenhang egal ist. Entscheidend sind ja die Aussagen, die er in seiner aktiven Zeit gemacht hat und genau diese aktive Zeit ist lange vorbei!)

Und nun? Kannst Du Deinen Kritikpunkt nun irgendwie belegen? Oder wieder mal eine unbelegte Aussage, die alle Anderen als Tatsache entgegen nehmen müssen?
 

mrBrown

Super-Moderator
Mitarbeiter
Der Link zu Dijkstra ist mir bekannt. Du solltest diesen aber lesen, da geht es um GOTO also einen Sprung. Das hat mit break gar nichts zu tun. Der Unterschied ist Dir aber scheinbar nicht geläufig.
Ersetz das break einfach durch ein return, dann ist er sicher zufriedengestellt :p

(Im Byte-Code entspricht ein break btw einem goto. Die Punkte von Dijkstra dürften für breaks in Verbindung mit Labeln genauso gelten)
Java:
private int labels() {
    label:
    {
        label2:
        if (new Random().nextBoolean()) {
            if (new Random().nextBoolean()) {
                break label2;
            }
            return 17;
        } else {
            break label;
        }

        return 42;
    }
    return 0;
}
 
X

Xyz1

Gast
Außerdem meinte ich damit, dass man nichtmehr irdische Personen schwer fragen kann, wie sie etwas gemeint haben. (Es sei denn, jemand versteht hier etwas von Okkultismus, aber das ist jetzt wirklich am Thema vorbei...)
 
K

kneitzel

Gast
break == goto statement ist (für mich) keine unzulässige Äquivalenz. *schulterzuck*

Damit sind dann für Dich also auch switch Statements, in denen break Statements vorkommen, nicht zulässig?

Ersetz das break einfach durch ein return, dann ist er sicher zufriedengestellt :p

(Im Byte-Code entspricht ein break btw einem goto. Die Punkte von Dijkstra dürften für breaks in Verbindung mit Labeln genauso gelten)

Dann ist aber auch gar nichts erlaubt, denn Sprünge (GOTO) sind ja generell das, was am Ende die CPU macht. Also wenn man die Trennung zwischen erstelltem Code und dem daraus generierten Code nicht hat, dann wird man nur noch einfache, gradlinige Software entwickeln können fürchte ich.
(Selbst ein Funktionsaufruf ist ja nur ein pushen von Werten auf den Stack gefolgt von einem Sprung. Und am Ende dann das herunternehmen von Werten vom Stack und dann ein Sprung zu der Rücksprungadresse....)
 

Blender3D

Top Contributor
break == goto statement ist (für mich) keine unzulässige Äquivalenz. *schulterzuck*
Die Anmerkung für mich ist wirklich notwendig. Du brauchst augenscheinlich einen Nachschulung für die Bedeutung Gleichheit.
GOTO. erlaubt den Sprung an eine beliebig definierte Stelle im Code.
break unterbricht eine Schleife. Genau das passiert auch in Deiner schwerer zu lesenden Version der Methode tick() in Deiner while Schleife auch.
Der Punkt ist mit break kann ich nicht an eine beliebige Stelle im Code springen. --> break != goto
Benutzt hier ein Anfänger den Account (seit 2015) von @Tobias-nrw ?
 

mrBrown

Super-Moderator
Mitarbeiter
break unterbricht eine Schleife. Genau das passiert auch in Deiner schwerer zu lesenden Version der Methode tick() in Deiner while Schleife auch.
Der Punkt ist mit break kann ich nicht an eine beliebige Stelle im Code springen. --> break != goto
Genauer springt break hinter einen gelabelten Block, auch unabhängig von Schleifen. Aber es erlaubt eben keine Rückwärtssprünge.
 

mrBrown

Super-Moderator
Mitarbeiter
Dann ist aber auch gar nichts erlaubt, denn Sprünge (GOTO) sind ja generell das, was am Ende die CPU macht. Also wenn man die Trennung zwischen erstelltem Code und dem daraus generierten Code nicht hat, dann wird man nur noch einfache, gradlinige Software entwickeln können fürchte ich.
(Selbst ein Funktionsaufruf ist ja nur ein pushen von Werten auf den Stack gefolgt von einem Sprung. Und am Ende dann das herunternehmen von Werten vom Stack und dann ein Sprung zu der Rücksprungadresse....)
Na so war das nicht gemeint :p
 
K

kneitzel

Gast
Ersetz das break einfach durch ein return, dann ist er sicher zufriedengestellt :p

Ach ja: Und bei Methoden gibt es ja für manch einen auch die Regel, dass man nur ein return Statement am Ende haben darf. Also nichts mit return vorher oder so ... Wer das break; so massiv ablehnt, der wird dies wohl auch ablehnen.

Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.

Aber das ist dann auch ein anderes Thema.

Außerdem meinte ich damit, dass man nichtmehr irdische Personen schwer fragen kann, wie sie etwas gemeint haben. (Es sei denn, jemand versteht hier etwas von Okkultismus, aber das ist jetzt wirklich am Thema vorbei...)

Also DU hast lediglich mit dem Namen eines Toten etwas begründen wollen. Und Du kannst das jetzt nicht begründen, weil die Person tot ist? Aber Du musst doch irgendwas von der Person wissen, wenn Du der Meinung warst, dass dies ein Argument für diese Sache ist.

Ach bitte, schlechter Verlierer würd ich mal sagen. ;) @Blender3D
Ihm geht es ja nur um eine Erläuterung der Kritik. Nur weil Du Deine Kritik nicht belegen / erläutern kannst, ist @Blender3D nun der schlechte Verlierer?

Kann man mir diese Logik evtl. etwas erläutern?
 

mrBrown

Super-Moderator
Mitarbeiter
Ach ja: Und bei Methoden gibt es ja für manch einen auch die Regel, dass man nur ein return Statement am Ende haben darf. Also nichts mit return vorher oder so ... Wer das break; so massiv ablehnt, der wird dies wohl auch ablehnen.

Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.

Aber das ist dann auch ein anderes Thema.
In Clean Code steht doch auch, dass mehrere returns durchaus besser sein können?

Some programmers follow Edsger Dijkstra’s rules of structured programming. Dijkstra said that every function, and every block within a function, should have one entry and one exit. Following these rules means that there should only be one return statement in a function, no break or continue statements in a loop, and never, ever, any goto statements.

While we are sympathetic to the goals and disciplines of structured programming, those rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefit.

So if you keep your functions small, then the occasional multiple return, break, orcontinue statement does no harm and can sometimes even be more expressive than the single-entry, single-exit rule. On the other hand, goto only makes sense in large functions, so it should be avoided.

(Bezieht sich sogar auf goto :p)
 

Blender3D

Top Contributor
(Im Byte-Code entspricht ein break btw einem goto. Die Punkte von Dijkstra dürften für breaks in Verbindung mit Labeln genauso gelten)
Da ich auch Assemblerprogramme schreibe, weiß ich natürlich auch dass im Byte Code dort ein Sprung stattfindet.
Dasselbe passiert aber auch bei einer abweisenden while Schleife im Byte Code oder wenn man return verwendet.
Der Punkt ist, dass BREAK <> GOTO ist. Warum?
Ich kann mittels break nicht an eine beliebige Stelle Springen. Also Logik:
A hat Eigenschaft 1 und 2.
B hat Eigenschaft 1.
--> A <> B
Und Dijkstra spricht in seinem Link von GOTO.
 
X

Xyz1

Gast
@Blender3D Spulen wir nochmal zurück bitte. Ich wollte damit nicht schreiben, Dein Code sei schlecht oder Ähnliches, aber eben auch nicht "fehlerfrei", bzw an der ein oder anderen Stelle hätte man ihn, zB in einem Review, anders schreiben können.

@ all : Ich kann nicht genau begründen, wie Dijkstra das evtl gemeint haben könnte. Aber @mrBrown hat ja bereits ein paar relevante Stellen herausgesucht...
 

mrBrown

Super-Moderator
Mitarbeiter
Der Punkt ist, dass BREAK <> GOTO ist.
[...]
Und Dijkstra spricht in seinem Link von GOTO.
Ich hab nirgends das Gegenteil behauptet.

Wenn man jedes GOTO ablehnt (was Dijkstra nicht getan hat) - auch die, die nur für Vorwärtssprünge genutzt werden - muss man den gleichen Maßstab aber auch für break ansetzen.

Setzt man einen sinnvollen Maßstab an (und weicht auch von single-entry/single-exit ab, weclhes für return, break & continue ebenso gilt), sind breaks völlig Okay, aber sowas wie Vorwärtssprünge mit Goto als Ersatz für finally aber auch. (Als reines Sprachfeature ist es mMn besser als goto, da begrenztere Nutzungsmöglichkeiten)

Das die Aussage von @Tobias-nrw so wie sie da stand dämlich ist, ist völlig klar. Aber je nachdem, wie hart man Dinge auslegt, sprechen die Dinge, die gegen goto sprechen, auch gegen breaks.

Ich kann mittels break nicht an eine beliebige Stelle Springen
Wenn man Blöcke sehr missbraucht, kann man immerhin an fast jede Stelle springen, nur z.B. nicht in andere, fremde Blöcke... Ist dann allerdings noch schlimmer als goto für sowas zu benutzen...
 
Zuletzt bearbeitet:

White_Fox

Top Contributor
Ich staune darüber, auf welche Abwege eine recht einfache Anfängeraufgabe führen kann.

Und welch ein Trubel um ein Statement, daß es im Hauptthemenbereich des Forums nicht gibt. ;)
 
X

Xyz1

Gast
Danke @mrBrown für Deine Unterstützung. Das Zitat oder der Beleg zeigt ja das ich nicht unrecht hatte mit meinen "Kritik"punkten. ;)

Hier gab es nur ein break; aber besonders, wenn sich die break;s häufen, tut das dem Lesefluss nicht gut...

An dem Beispiel sieht man auch, dass seine Thesen keinesfalls "in die Jahre gekommen", vielmehr aktueller denn je sind.
 
X

Xyz1

Gast
public void tick() { int time; int i = 0; do { time = (this.time = countUpValue(this.time, max)); i++; } while (time == 0 && i < max.length); }
Ich weiß jetzt wieder, warum ich heute Morgen die Variable time hinzunahm... Weil i in der Schleife erhöht wird und i-1 ein zusätzlicher und unübersichtlicher Rechenschritt ist.
 

mihe7

Top Contributor
Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.
Grundsätzlich versuche ich, mich schon daran zu halten, habe aber kein Problem mit Ausnahmen. Typisches Beispiel:

Java:
public boolean equals(Object o) {
    if (o == null || o == this || !(o instanceof MeineKlasse)) {
        return o == this;
    }

    MeineKlasse k = (MeineKlasse) o;
    return Objects.equals(this.value, k.value);
}
ist für mich am angenehmsten zu lesen. Andererseits schreibe ich for-each-Schleifen in der Regel nicht, wenn dies zu einem return/break führen würde (Ausnahmen gibt es immer).
 
K

kneitzel

Gast
Grundsätzlich versuche ich, mich schon daran zu halten, habe aber kein Problem mit Ausnahmen. Typisches Beispiel:

Java:
public boolean equals(Object o) {
    if (o == null || o == this || !(o instanceof MeineKlasse)) {
        return o == this;
    }

    MeineKlasse k = (MeineKlasse) o;
    return Objects.equals(this.value, k.value);
}
ist für mich am angenehmsten zu lesen. Andererseits schreibe ich for-each-Schleifen in der Regel nicht, wenn dies zu einem return/break führen würde (Ausnahmen gibt es immer).

Also es ist schon oft so, dass man bei Funktionen am Ende das Ergebnis zurück gibt, aber ich denke, dass es nicht selten vorkommt, dass man eben aus einer Menge etwas heraus suchen muss und dann natürlich die Suche abbricht.

Und da sehe ich nun als einzige Alternative, eben auf das for statement zu verzichten und es generell per while Schleife ablaufen zu lassen. Aus dem Code
Code:
for(SomeType elment: elements) { 
    ...
    if (someCondition) return someExpression;
}
wird dann halt etwas wie (Pseudocode im Browser hier entstanden
Code:
Iterator<SomeType> iterator = elements.getIterator();
SomeType result = null;
while (result==null && iterator.hasNext()) {
    SomeType element = iterator.next();
    ...
    if (someCondition) result=someExpression;
}
return result;
Oder man schwenkt natürlich auf streams um mit elements.stream().filter(...).First(); was bei halbwegs aktuellem Java (Java 8 Minimum) gehen würde. Nur bei komplexerem Filter bin ich mir jetzt nur nicht sicher, ob dies lesbar bleibt. (Aber vermutlich schon. Complexe Dinge würde ich in den anderen Varianten ja auch nicht in der Schleife ablaufen lassen sondern eben verlagern. Das wird da ja auch gelten...

Habe ich da jetzt etwas übersehen? Das mit der While Schleife würde ich erst einmal als schwerer lesbarer ablehnen. Das mit der Streams API sieht aber tatsächlich gut aus und zeigt, dass meine bisherige Haltung diesbezüglich evtl. durch die Einführung der Streams API anzupassen ist.
 

mihe7

Top Contributor
Das mit der While Schleife würde ich erst einmal als schwerer lesbarer ablehnen.
Jein. Es ist zweifelsohne mehr Code, der aus Sicht von Anfängern zunächst schwerer zu begreifen ist (Iterator-Konzept). Tatsächlich ist das aber alles Standard-Boilerplate-Code. Dieses Muster findet man also so gut wie immer, wenn mit Iteratoren gearbeitet wird.

Tatsächlich sagt das while aber wesentlich präziser, worum es geht: iteriere so lange, bis result != null ist. Das for-Each lügt mir dagegen ins Gesicht: es tut so, als ob über alle Elemente iteriert würde, tatsächlich bricht es irgendwann ab und springt auch noch aus der Methode.

Wenn man die Blöcke einklappt, wird deutlicher, was ich meine:
Java:
for (SomeType element : elements) { ... }
return null;
vs
Java:
while (result == null && it.hasNext()) { ... }
return result;

Für so etwas würde ich heute allerdings auch Streams verwenden :)

(EDIT: Schleifenbedingung korrigiert)
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Jein. Es ist zweifelsohne mehr Code, der aus Sicht von Anfängern zunächst schwerer zu begreifen ist (Iterator-Konzept). Tatsächlich ist das aber alles Standard-Boilerplate-Code. Dieses Muster findet man also so gut wie immer, wenn mit Iteratoren gearbeitet wird.

Tatsächlich sagt das while aber wesentlich präziser, worum es geht: iteriere so lange, bis result != null ist. Das for-Each lügt mir dagegen ins Gesicht: es tut so, als ob über alle Elemente iteriert würde, tatsächlich bricht es irgendwann ab und springt auch noch aus der Methode.

Diese Argumentation kann ich nachvollziehen, aber wirklich überzeugt bin ich nicht. :)
Im Augenblick empfinde ich die While Scheife auf Grund des Boilerplate Codes eher als unleserlicher. Aber auch der logische Ablauf ist bei der while schleife deutlicher, da hier eine Bedingung ist. Bei der for Schleife hat man das ja unterteilt in einmal die Definition über was iteriert werden soll + einer if Abfrage innen drin. (if (Bedingung) return result; ist ja existenziell.

Aber ich werde auf jeden Fall einmal in der Praxis schauen, ob die while schleife deutlicher wird (Ist ja auch eine Frage der Gewöhnung) und ich werde auch einmal den Smalltalk im Team darauf lenken. (Akzeptiert sind da beide Wege.)
 
K

kneitzel

Gast
Du vergleichst Äpfel und Birnen... Es ging nicht um ein return; sondern um das noch schädlichere break;.

Und naja, da bleibt nur zu hoffen, dass Du nicht etwas ablehnen kannst...
Bitte lies einen Thread, ehe Du antwortest. In den letzten Beiträgen (ab #33) ging es eben nicht mehr um das "break;" oder "return" sondern um die Konsequenzen. Und da gab es im Thread drei Optionen für die Implementierung: for-each, while und Streams.

Und genau die wurden bewertet. Da kannst Du auch gerne Deine Sicht sagen.

@mihe7 Interessant ist, wenn "null" ein mögliches Resultat wird und bei nicht Vorhandensein eines Resultates eine Exception geworfen werden soll. Das verkompliziert die while-Lösung etwas. Da wäre mein Ansatz dann, Optional<ResultTyp> zu verwenden. Dann kann man halt result.isPresent in der while Bedingung und ein abschließendes if nach der while schleife...

Da wird das mit der Stream API doch deutlich einfacher und übersichtlicher.
 

mihe7

Top Contributor
Diese Argumentation kann ich nachvollziehen, aber wirklich überzeugt bin ich nicht.
Das sind ja auch nur persönliche Präferenzen - und die sind nun einmal individuell verschieden :)

Interessant ist, wenn "null" ein mögliches Resultat wird und bei nicht Vorhandensein eines Resultates eine Exception geworfen werden soll. Das verkompliziert die while-Lösung etwas.
Darin unterscheiden sich while und for-each aber nicht - oder ich habe Dich falsch verstanden.
 
K

kneitzel

Gast
Darin unterscheiden sich while und for-each aber nicht - oder ich habe Dich falsch verstanden.
Das Problem, welches ich meine ist: Angenommen es kann auch null als Ergebnis heraus kommen. Also ich habe etwas wie:
Code:
for (Element element: elements) {
  if (someCheck(element)) return element.getValue();
}
// Hier ist klar: element wurde nicht gefunden - kann also Exception werfen oder default Wert zurück geben oder oder oder ...

Die 1:1 Übersetzung hinkt aber:
Code:
while (result == null && it.hasNext()) {
  Element element = it.next();
  if (someCheck(element)) result = element.getValue();
}
Aber da bricht dann ja auch noch nicht einmal die Schleife ab, wenn getValue() auch null liefern kann/darf.

Aber das war ein Denkfehler bei mir. Denn wenn man es aufschreibt, dann wird klar: ich kann ja einfach der element in result speichern. Das ist dann nicht null und ich kann am Ende auch schauen: Wenn result == null, dann gebe ich default Wert zurück oder werfe eine Exception ... also gar kein Thema, das zu diskutieren wäre und auch nichts, das neue Argumente in die Diskussion einbringt. Also an der Stelle sorry für evtl. Verwirrungen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Problem WIE ohne Goto-Befehl lösbar? Java Basics - Anfänger-Themen 6
N Benötige eine Alternative für einen GOTO Befehl Java Basics - Anfänger-Themen 2
iB0T Eine Art Goto Befehl! Java Basics - Anfänger-Themen 27
M Erneutes Ausführen bestimmter Aktionen (GoTo-Alternative) Java Basics - Anfänger-Themen 6
S goto? Java Basics - Anfänger-Themen 15
D Goto - Anweisung Java Basics - Anfänger-Themen 11
Z Digitaluhr, Hilfe ! Java Basics - Anfänger-Themen 24
T Laufende Digitaluhr Java Basics - Anfänger-Themen 3
Kerstininer Vererbung Hilfe beim lernen von Objektorientierung für eine Klausur Java Basics - Anfänger-Themen 10
R Umgebungsvariable java -cp gibt immer Java-Hilfe... Java Basics - Anfänger-Themen 3
E Hilfe bei rekursiver Funktion Java Basics - Anfänger-Themen 3
H pdf stempel - Hilfe erbeten Java Basics - Anfänger-Themen 6
KogoroMori21 Wann ist der richtige Zeitpunkt, um sich Hilfe zu suchen? (Bin Informatik-Student) Java Basics - Anfänger-Themen 10
A Hilfe beim Lesen von Pfaden und Systemvariablen Java Basics - Anfänger-Themen 3
F RegEx Hilfe Java Basics - Anfänger-Themen 5
S Hilfe bei Endlosschleife Java Basics - Anfänger-Themen 2
S Hilfe bei Praktischen Aufgaben von Arrays Java Basics - Anfänger-Themen 39
U Ich bräuchte Hilfe Java Basics - Anfänger-Themen 1
Say abstract class und Objekt erzeugen - Dringend Hilfe Java Basics - Anfänger-Themen 10
Justin4687 Benötige Hilfe bei folgender Aufgabe Java Basics - Anfänger-Themen 2
aero043 Hilfe bei BlueJ Hausübung Java Basics - Anfänger-Themen 27
S Hilfe zu einer Aufgabe Java Basics - Anfänger-Themen 5
P Hilfe gesucht Java Basics - Anfänger-Themen 11
D Hilfe bei Calculator Test Java Basics - Anfänger-Themen 15
R Hilfe bei Aufgabe Java Basics - Anfänger-Themen 4
Zentriks Hilfe zu Sieb des Eratosthenes ohne boolean Java Basics - Anfänger-Themen 5
R Java Bücher hilfe Java Basics - Anfänger-Themen 9
U HILFE! - per ActionListener Felder enablen....... Java Basics - Anfänger-Themen 5
I Scheduling: "Quartz" verwenden, Hilfe bei Umstellung Java Basics - Anfänger-Themen 3
I Hilfe bei Klausur Frage Java Basics - Anfänger-Themen 8
L Hilfe! Liste mit Items werden ausgegeben aber nicht in zufälliger Reihenfolge Java Basics - Anfänger-Themen 6
Ekooekoo Hilfe spiel Java Basics - Anfänger-Themen 5
SpiritsHuner Hilfe!! Java Basics - Anfänger-Themen 16
Lacotto Java Kurs Aufgaben Hilfe Java Basics - Anfänger-Themen 14
V Hilfe bei Implementierung einer boolean Methode Java Basics - Anfänger-Themen 6
M HILFE JPanel - Graphics Java Basics - Anfänger-Themen 1
D Hilfe bei einer Aufgabe mit for-Schleife Java Basics - Anfänger-Themen 6
X Hilfe beim Übertragen in eine For-Schleife Java Basics - Anfänger-Themen 1
Neuling47 Denkfehler? Hilfe Java Basics - Anfänger-Themen 11
S Hilfe bei Umänderung von Java Code Java Basics - Anfänger-Themen 16
Robert_Klaus Hamster java Simulation Hilfe bei einer Aufgabe Java Basics - Anfänger-Themen 5
X Erste Schritte Hilfe bei einem kleinen Spiel. Java Basics - Anfänger-Themen 19
D Bitte um Hilfe muss es schnellstmöglich erledigen Java Basics - Anfänger-Themen 15
L Hilfe bei RegEx Java Basics - Anfänger-Themen 4
I Bitte um Hilfe zu unterstehenden Code Java Basics - Anfänger-Themen 6
B Brauche Hilfe zu einem Code Java Basics - Anfänger-Themen 5
Neuling47 bräuchte dringend hilfe Java Basics - Anfänger-Themen 6
D Bräuchte Hilfe im Bezug zum printarray() Java Basics - Anfänger-Themen 4
M Bitte um Hilfe bei 2DArrays Java Basics - Anfänger-Themen 8
HeiTim Array hilfe Java Basics - Anfänger-Themen 14
M LCD-Ziffern-Hilfe Java Basics - Anfänger-Themen 6
özkan hilfe!! Java Basics - Anfänger-Themen 4
C Hilfe bei einem Anfängerprojekt Java Basics - Anfänger-Themen 25
D Abrechnung bitte um hilfe Java Basics - Anfänger-Themen 25
J Brauche Hilfe bei for-each Aufgabe Java Basics - Anfänger-Themen 1
D Zahlentabelle Anfänger braucht Hilfe Java Basics - Anfänger-Themen 1
HeiTim Brauche Hilfe soll ein nummeriertes Feld ausgeben lassen Java Basics - Anfänger-Themen 17
S Interaktive Abfrage, Hilfe mit Schleifen! Java Basics - Anfänger-Themen 6
N Hilfe bei der Installation Java Basics - Anfänger-Themen 2
J Brauche Hilfe bei Aufgabe Java Basics - Anfänger-Themen 4
S Hilfe bei Programmierung einer Hotelabrechnung Java Basics - Anfänger-Themen 5
enjoykimii Strukturierte Programmierung Hilfe Java Basics - Anfänger-Themen 29
H Bräuchte hilfe Java Basics - Anfänger-Themen 3
D Snake-Spiel ähnliche Aufgabe Hilfe Java Basics - Anfänger-Themen 3
H Brauche Hilfe Java Basics - Anfänger-Themen 2
D Dijkstra Algorithmus Hilfe!! Java Basics - Anfänger-Themen 9
H Hilfe Java Basics - Anfänger-Themen 6
H Brauche hilfe Java Basics - Anfänger-Themen 3
M Hilfe - Array Aufgabe Java Basics - Anfänger-Themen 8
R Schulaufgabe, Bruache Hilfe mit non-static Methoden Java Basics - Anfänger-Themen 2
kevkev Hilfe bei Schiffe versenken Java Basics - Anfänger-Themen 5
FelixxF Erste Schritte Hilfe bei Fußball Manager Java Basics - Anfänger-Themen 2
C Brauche Hilfe beim Schreiben eines Programmes :/ Java Basics - Anfänger-Themen 1
C Brauche Hilfe um ein Programm zu schreiben Java Basics - Anfänger-Themen 8
josfe1234 Hilfe access denied ("java.io.FilePermission" " " "read") Java Basics - Anfänger-Themen 12
Vivien Hilfe bei Type Conversion Java Basics - Anfänger-Themen 3
Leo0909 Ich brauche Hilfe bei dieser Aufgabe Java Basics - Anfänger-Themen 2
D Hilfe beim Erzeugen eines Arrays NullPointerException wird ausgelöst Java Basics - Anfänger-Themen 11
J Doppelt verkette Liste ich bitte um Hilfe Java Basics - Anfänger-Themen 4
N Laufzeitberechnung - dringende Hilfe! Java Basics - Anfänger-Themen 1
G Java Hilfe Java Basics - Anfänger-Themen 3
J Java List, Bitte um Hilfe Java Basics - Anfänger-Themen 15
J Java List, bitte um Hilfe Java Basics - Anfänger-Themen 3
U anfänger braucht hilfe . wir konnten die aufgaben nicht beantworten Java Basics - Anfänger-Themen 5
A Schleifen, Hilfe! Java Basics - Anfänger-Themen 6
LeonDerStudent Hilfe bei Uniprojekt Java Basics - Anfänger-Themen 2
H Brauche Hilfe in Java Eclipse Programmieraufgabe Neuling Java Basics - Anfänger-Themen 3
B Hilfe bei Map Liste erstellen Java Basics - Anfänger-Themen 10
Kapfski Was habe ich falsch gemacht? Hilfe! Java Basics - Anfänger-Themen 17
R Java (Eclipse) "Lagerverwaltung" HILFE Java Basics - Anfänger-Themen 13
M Bräuchte Hilfe bei diesen Methoden Java Basics - Anfänger-Themen 4
dieter000 Aufgabe Hilfe Java Basics - Anfänger-Themen 18
Gaudimagspam Dringend Java Hilfe benötigt Java Basics - Anfänger-Themen 19
jonathanpizza Hilfe bei einer Übungsaufgabe Java Basics - Anfänger-Themen 6
dieter000 Hilfe bei dem Beispiel, wie gehe ich sowas am besten an? Java Basics - Anfänger-Themen 32
jonathanpizza Hilfe bei einer Aufgabe Java Basics - Anfänger-Themen 5
Q Hilfe auf Aufgabe(Matrixmultiplikation) Java Basics - Anfänger-Themen 1
jonathanpizza Hilfe bei der Aufgabe Java Basics - Anfänger-Themen 19
pry bitte Hilfe beim Kreditrechner objektorientiert Java Basics - Anfänger-Themen 6
R Hilfe bei removeduplicates Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben