Beispiel Programm Zufallszahlen ohne Wiederholung

Bitte aktiviere JavaScript!
Verwendete Elemente:

/*
* Scanner-Benutzereingabe
* Random-Zufallszahlen generieren
* Exception try-catch
* Label-continue
* foreach-schleife
* BigInteger für sehr große Zahlen
* Methoden
*/

Java:
public class Lotto {

    public static void main(String[] args){
      
        int givenValue[] = new int[6];
        int randomValue[] = new int[6];
        int hits = 0;            //für gefundene zahlen

        givenValue = determineGivenNumbers();    //Methode für UserInput
        randomValue = determineRandomNumbers();    //Methode für Zufallszaheln generieren
        hits = checkForEquality(givenValue, randomValue);    //prüft die Arrays auf gleichheit

        printArrays(givenValue, randomValue, hits);        //gibt die Arrays und die ermittelten Treffer aus
        binomialkoeffizient();        //Die Wahrscheinlichkeit von 6 Treffer aus 49 ausrechen
    }

/*----------------------------UserInput---------------------------------------*/
    public static int[] determineGivenNumbers(){
      
        int givenValue[] = new int[6];
        Scanner scan = new Scanner(System.in);
        int checkGivNumber = 0;        //damit nicht gleiche zahlen eingegeben werden können
        boolean numOrLetter = false;//damit nicht buchstaben eingegeben werden können
      
        System.out.println("Please enter six numbers 1-49!");
      
        Böö: for(int i=0; i<givenValue.length; i++){
            do{
                try{
                    numOrLetter = false;
                    checkGivNumber = scan.nextInt();
                }catch(Exception e){
                    System.err.println("Please enter a valid number! " + e.toString());
                    scan.nextLine();
                    numOrLetter = true;        //wenn buchstabe eingegeben wird fehler, nochmal abfragen
                }
                if(checkGivNumber <= 0 || checkGivNumber > 49) System.err.println("Please give a number in the specifield range!");
            }while(checkGivNumber <= 0 || checkGivNumber > 49 || numOrLetter == true);
          
            for(int j=0; j<i; j++){
                if(givenValue[j] == checkGivNumber){    //Falls eingegebene Zahl doppelt
                    System.err.println("The entered number is already exists!");
                    System.out.println("Please enter a new number!");
                    i--;    //wenn gleiche zahl dann for-schleife nicht weiter iterieren
                    continue Böö;            //dann gehe zu Böö, nach continue wird dann nichts mehr ausgeführt
                }
            }
            givenValue[i] = checkGivNumber;
        }
      
        Arrays.sort(givenValue);
      
        return givenValue;
    }
/*----------------------------------------------------------------------------*/
  
/*--------------------------Random Zufallszahlen------------------------------*/
    public static int[] determineRandomNumbers(){
      
        int randomValue[] = new int[6];
        Random rNumber = new Random();
        int checkRanNumber = 0;        //damit nicht gleiche random zahlen generiert werden
      
        Böö: for(int i=0; i<randomValue.length; i++){
            checkRanNumber = rNumber.nextInt(49)+1;
            for(int j=0; j<i; j++){
                if(randomValue[j] == checkRanNumber){  
                    i--;
                    continue Böö;                      
                }
            }
            randomValue[i] = checkRanNumber;
        }
      
        Arrays.sort(randomValue);
      
        return randomValue;
    }
/*----------------------------------------------------------------------------*/
  
/*------------------------Arrays auf Gleichheit prüfen------------------------*/
    public static int checkForEquality(int givenValue[], int randomValue[]){
        int hits = 0;
        //Array auf überprüfen, wieviel Zahlen gleich sind
        for(int j=0; j<randomValue.length; j++){
            for(int i=0; i<givenValue.length; i++){
                if(givenValue[i] == randomValue[j]){
                    hits++;
                }
            }  
        }
        return hits;
    }
  
/*----------------------------------------------------------------------------*/
  
/*-----------------Arrays und die ermittl. Treffer ausgeben-------------------*/
    public static void printArrays(int givenValue[], int randomValue[], int hits){
        for(int i : givenValue){
            System.out.print(i + "\t");
        }
        System.out.println();
        for(int i : randomValue){
            System.out.print(i + "\t");
        }
        System.out.println("You have " + hits + " hits!");
    }
/*----------------------------------------------------------------------------*/
  
/*-----------Die Wahrscheinlichkeit von 6 Treffer aus 49 ausrechen------------*/
    public static void binomialkoeffizient(){
      
        BigInteger result = BigInteger.ONE;
        int n = 49;
        int k = 6;
      
        result = faculty(n).divide(faculty(k).multiply((faculty(n-k))));
        System.out.println("The propability for six correct hits are 1 : " + result);
        double d1 = result.doubleValue();    //den BigInteger wert in double umwandeln
        System.out.println(1/d1 + " %");    //damit es in % anzahl angegeben kann
    }
  
    //Die BigInteger-Objekte werden dabei immer so lang,
    //wie die entsprechenden Ergebnisse Platz benötigen
    public static BigInteger faculty(int number){
        if(number <= 1) return BigInteger.ONE;
        return BigInteger.valueOf(number).multiply(faculty(number-1));
        //BigInteger.valueOf(long val) Erzeugt ein BigInteger, das den Wert val annimmt
        //mit .multiply wird this * multiply(zahl) gemacht
    }
}
 
Zuletzt bearbeitet von einem Moderator:
Keine Probleme, hab es als Bsp reingestellt, für Anfänger.
Ein paar kleine Anregungen zum Code habe ich:

Vermeide solche Einzeiler ;)
Java:
...
if(checkGivNumber <= 0 || checkGivNumber > 49) System.err.println("Please give a number in the specifield range!");
...
if(number <= 1) return BigInteger.ONE;
...
Ein Anfänger der mit dem Code herumspielt und vielleicht einen dieser if-Zweige erweitern will fliegt auf die Schnauze weil er vergisst Klammern zu machen.

Statt deinen Kommentare für Methode
/*--------------------------Random Zufallszahlen------------------------------*/
verwende doch übliches JavaDoc. Beschreibe damit genauer was die Methode macht, was die Parameter bedeuten und was der Rückgabewert ist.

Java:
}catch(Exception e) {
   System.err.println("Please enter a valid number! " + e.toString());
   scan.nextLine();
   numOrLetter = true;        //wenn buchstabe eingegeben wird fehler, nochmal abfragen
}
Ich weiß es zwar, aber ein Anfänger wird sich fragen warum du hier scan.nextLine() aufrufst aber das eingelesene nicht verwendest.
Hier wäre noch ein Kommentar meiner Meinung nach wichtig.

Java:
int givenValue[] = new int[6];
int randomValue[] = new int[6];
...
givenValue = determineGivenNumbers();    //Methode für UserInput
randomValue = determineRandomNumbers();    //Methode für Zufallszaheln generieren
Die "[]" sollten bei dem Typ stehen nicht hinter dem Variablen Name! Du hast ein Array von "int" nicht ein Array von "givenValue", außerdem ist so die Typinformation getrennt und nicht auf einen Blick ersichtlich.
Du initialisierst die Arrays zwar, aber überschreibst sie dann wieder mit dem Rückgabewert der Methode. -> die Initialisierung ist unnötig.
 
@Flown der Code funktioniert ohne Fehler, aber natürlich können Kritik Anregungen und Verbesserungsvorschläge gemacht werden.

@Joose vielen Dank für deine Anregungen, das mit den Klammern [] bei den Arrays ist mir noch von C hängengeblieben :D

Meinst du es so?
Code:
        int givenValue[] ;
        int randomValue[];
        int hits = 0;            //für gefundene zahlen

        givenValue = determineGivenNumbers();    //Methode für UserInput
        randomValue = determineRandomNumbers();
 
@Joose vielen Dank für deine Anregungen, das mit den Klammern [] bei den Arrays ist mir noch von C hängengeblieben :D
Ja dem Compiler ist es auch egal und du bist auch nicht der einzige der es so macht. Wers unbedingt so machen will soll es eben so machen, aber ich finde es eben besser wenn die ganze Typ Information beisammen ist.

Ja oder direkt so
Java:
int[] givenValue = determineGivenNumbers();
 
Hallo javaerd,

dies ist verpönt (die Kennzeichnung deines Codes):
Java:
Böö: for(int i=0; i<givenValue.length; i++){
Dies kann vereinfacht werden:
Java:
while(checkGivNumber <= 0 || checkGivNumber > 49 || numOrLetter == true);
Java:
while(checkGivNumber <= 0 || checkGivNumber > 49 || numOrLetter);
Für jede Schleife hat eine bessere Lesbarkeit:
Java:
for(int j=0; j<randomValue.length; j++){
           for(int i=0; i<givenValue.length; i++){
               if(givenValue[i] == randomValue[j]){
                   hits++;
               }
           }
       }
Java:
for (int i : randomValue) {
           for (int value : givenValue) {
               if (value == i) {
                   hits++;
               }
           }
       }
Fehlermeldung entspricht nicht den Ausnahmen, die auftreten können:
Java:
try{
                   numOrLetter = false;
                   checkGivNumber = scan.nextInt();
               }catch(Exception e){
                   System.err.println("Please enter a valid number! " + e.toString());
                   scan.nextLine();
                   numOrLetter = true;        //wenn buchstabe eingegeben wird fehler, nochmal abfragen
               }


Anstatt ein Array zu verwenden, kann der Code mithilfe einer ArrayList und durch Aufrufen der Contains-Methode vereinfacht werden. Du solltest generische Typen Arrays vorziehen. Arrays sind unflexibel und haben nicht die Ausdruckskraft von generischen Typen:
Java:
public static int[] determineGivenNumbers(){

       int givenValue[] = new int[6];
...
for(int j=0; j<i; j++){
               if(givenValue[j] == checkGivNumber){    //Falls eingegebene Zahl doppelt
                   System.err.println("The entered number is already exists!");
                   System.out.println("Please enter a new number!");
                   i--;    //wenn gleiche zahl dann for-schleife nicht weiter iterieren
                   continue Boo;            //dann gehe zu Böö, nach continue wird dann nichts mehr ausgeführt
               }
           }
Java:
List<Integer> userIntegers = new ArrayList<>();
       if (userIntegers.contains(1)) // Benutzer eine Warnung anzeigen, da 1 bereits in der Liste enthalten ist;
Dies kann vereinfacht werden:
Java:
boolean numOrLetter = false;
Java:
boolean numOrLetter;
Rechtschreibfehler:
Java:
System.out.println("The propability for six correct hits are 1 : " + result);
Java:
System.out.println("The probability for six correct hits are 1 : " + result);
Du deklarierst einen Scanner, der Closeable implementiert. Es wird empfohlen, den Scanner zu SCHLIESSEN, wenn du damit fertig bist:
Java:
Scanner scan = new Scanner(System.in);
scan.close();
numOrLetter = false sollte sich nicht in deiner try-Anweisung befinden, sondern über der try-Anweisung stehen:
Java:
try{
                   numOrLetter = false;
                   checkGivNumber = scan.nextInt();
               }catch(Exception e){
                   System.err.println("Please enter a valid number! " + e.toString());
                   scan.nextLine();
                   numOrLetter = true;        // wenn buchstabe eingegeben wird fehler, nochmal abfragen
               }
Java:
numOrLetter = false;
try{
                   checkGivNumber = scan.nextInt();
               }catch(Exception e){
                   System.err.println("Please enter a valid number! " + e.toString());
                   scan.nextLine();
                   numOrLetter = true;        // wenn buchstabe eingegeben wird fehler, nochmal abfragen
               }
Du rufst scan.nextLine () ohne Ausnahmebehandlung auf:


Wenn ich eine Firma hätte und ich gesehen hätte, dass jemand dies in meiner Firma festschrieb und versuchte, dies mit der Hauptniederlassung zusammenzuführen, hätte ich die die Zusammenführungsanforderung sofort abgelehnt. Bitte stelle ihn entsprechend ein und versuche es erneut. Du schreibst Code wie ein C-Programmierer der alten Schule. Das ist Java.

Grüße
 
Wenn ich eine Firma hätte und ich gesehen hätte, dass jemand dies in meiner Firma festschrieb und versuchte, dies mit der Hauptniederlassung zusammenzuführen, hätte ich die die Zusammenführungsanforderung sofort abgelehnt.
Noch besser wird es, wenn man den offensichtlich per Google Translate übersetzten Satz erneut durch Deutsch -> Englisch -> Deutsch schickt:
"Wenn ich eine Firma gehabt hätte und jemanden gesehen hätte, der dies in meine Firma schreibt und versucht, es mit der Zentrale in Einklang zu bringen, hätte ich den Zusammenschlussantrag sofort abgelehnt." :D

Außerdem: Du antwortest hier auf einen schon fast zweieinhalb Jahre alten Thread.
 
Zuletzt bearbeitet:
Immerhin hast du dich seit deinen letzten Posts mal mit Java auseinander gesetzt...

Du solltest generische Typen Arrays vorziehen. Arrays sind unflexibel und haben nicht die Ausdruckskraft von generischen Typen:
Würd ich nicht so generalisieren, vor allem verhindern Arrays hier Boxing und null.


Du deklarierst einen Scanner, der Closeable implementiert. Es wird empfohlen, den Scanner zu SCHLIESSEN, wenn du damit fertig bist:
Allerdings nutzt der Scanner System.in, welches trotz Closeable nicht geschlossen werden sollte...
 
Wie genau verhindern Arrays null?
In ’nem int-Array kann kein null stehen, in einer ArrayList<Ineger> schon.


Es ist empfehlenswert, einen stream zu schließen, nachdem du damit fertig bist, da dies zu einem Speicherverlust führen kann.
Das sollte man nur mit Streams, die man selber öffnet. Und Sytem.in öffnet die JVM und den schließt sie.
Den einfach zu schließen, wo man ihn grad benutzt, führt nur zu Problemen - wenn man ihn schließt, dann nur am Ende der Main, wenn es nur einen Thread im Programm gibt.

Probleme gibt es bei System.in absolut keine, vorallem kann es da nicht zu Speicherverlust kommen...
 
Hallo mrBrown und mihe7,

In ’nem int-Array kann kein null stehen, in einer ArrayList<Ineger> schon.
Arrays primitiver Typen können kein null aufnehmen.
Ihr verpasst völlig den Punkt. Sicher, eine ArrayList kann Null-Werte enthalten, und ihr solltet das berücksichtigen, aber den Code von javaerd könnte dann einfacher, leichter zu lesen sein und könnte im Allgemeinen den Codestandards entsprechen, die ich oben erklärt habe.

Das sollte man nur mit Streams, die man selber öffnet. Und Sytem.in öffnet die JVM und den schließt sie.
Den einfach zu schließen, wo man ihn grad benutzt, führt nur zu Problemen - wenn man ihn schließt, dann nur am Ende der Main, wenn es nur einen Thread im Programm gibt.

Probleme gibt es bei System.in absolut keine, vorallem kann es da nicht zu Speicherverlust kommen...
Wenn du der Meinung bist, dass die Java Virtual Machine dein One-Way-Ticket ist, um im Code von javaerd Speicherverluste zu hinterlassen, dann irrst du dich ernsthaft. javaerd schließt den Scanner nicht richtig. Man sollte javaerd darum bitten, es entsprechend anzupassen. Es ist mir egal, ob javaerd System.in verwendet. Wenn javaerd möchte, dass sein System.in geöffnet bleibt, sollte er sein System.in-Stream in einem CloseShieldInputStream verpacken, der verhindert, dass es geschlossen wird.

Grüße
 
eine ArrayList kann Null-Werte enthalten
Etwas anderes hat niemand behauptet.

@mrBrown hat festgestellt, dass im konkreten Fall ("hier") ein Array Boxing und null verhindert, worauf hin Du nachgefragt hast, inwiefern ein Array null verhindern würde. Die Antwort lautet, dass Arrays primitiver Typen kein null aufnehmen können. In einem int[] x wirst Du kein null finden. In einer List<Integer> dagegen schon.

EDIT: nur damit wir nicht aneinander vorbeischreiben: da ist keine Wertung enthalten. Wenn der Code - wie von Dir in Kommentar #8 angemerkt - durch eine List besser wird, warum nicht?

Wenn javaerd möchte, dass sein System.in geöffnet bleibt, sollte er sein System.in-Stream in einem CloseShieldInputStream verpacken, der verhindert, dass es geschlossen wird.
Die Idee gefällt mir (aber bitte nicht mit einer externen Library).

Wenn du der Meinung bist, dass die Java Virtual Machine dein One-Way-Ticket ist, um im Code von javaerd Speicherverluste zu hinterlassen, dann irrst du dich ernsthaft
Wo siehst Du denn hier Speicherverluste?
 
Zuletzt bearbeitet:
Ihr verpasst völlig den Punkt. Sicher, eine ArrayList kann Null-Werte enthalten, und ihr solltet das berücksichtigen, aber den Code von javaerd könnte dann einfacher, leichter zu lesen sein und könnte im Allgemeinen den Codestandards entsprechen, die ich oben erklärt habe.
Du verpasst da auch den Punkt: nur weil du deine Meinung zu einem bestimmten Punkt erklärte, ist das noch lange kein Standard. ;)
Er braucht genau 6 primitive Elemente - und genau das erfüllt ein Array. Eine ArrayList macht das an der Stelle weder einfach, noch leichter lesbar, noch genügt das irgendeinem verbreitetem Codestyle. Die von dir genannten Punkt ("unflexibel", "generisch") sind in diesem Fall kein Problem, sondern eher gewünscht - generische Typen sind hier eher problematisch (es sollen ja immer ints sein) und Flexibilität braucht man auch nicht (es sollen ja immer 6 sortierte Elemente sein).

Der einzige Vorteil einer List wäre das contains, das ginge in diesem Fall aber mit binarySearch.

Wenn man wirklich was Ausdrucksstärkeres will, bieten sich statt Listen eher SortedSets an, die sind immer Sortiert und verhindern direkt Dublikate - genau das, was hier ja benötigt wird.


Wenn javaerd möchte, dass sein System.in geöffnet bleibt, sollte er sein System.in-Stream in einem CloseShieldInputStream verpacken, der verhindert, dass es geschlossen wird.
Grad mal eben bei Stackoverflow vorbeigeguckt? ;) Externe Lib für so ein Mini-Programm ist aber wirklich nicht nötig...

Wenn du der Meinung bist, dass die Java Virtual Machine dein One-Way-Ticket ist, um im Code von javaerd Speicherverluste zu hinterlassen, dann irrst du dich ernsthaft.
Um mich mal selbst zu zitieren:
Probleme gibt es bei System.in absolut keine, vorallem kann es da nicht zu Speicherverlust kommen...
Falls du das anders siehst, dann "irrst du dich ernsthaft."
 
Hallo mihe7,

Etwas anderes hat niemand behauptet.

@mrBrown hat festgestellt, dass im konkreten Fall ("hier") ein Array Boxing und null verhindert, worauf hin Du nachgefragt hast, inwiefern ein Array null verhindern würde. Die Antwort lautet, dass Arrays primitiver Typen kein null aufnehmen können. In einem int[] x wirst Du kein null finden. In einer List<Integer> dagegen schon.

EDIT: nur damit wir nicht aneinander vorbeischreiben: da ist keine Wertung enthalten. Wenn der Code - wie von Dir in Kommentar #8 angemerkt - durch eine List besser wird, warum nicht?
Das wäre richtig. Zum Beispiel bei einer Klasse, die eine ROT13-Ausgabe generiert, würde ich Arrays anstelle von Listen verwenden. Der Grund wäre, dass sich die allgemeine Funktionsweise der Methoden nicht kurzfristig ändert.

Ein weiteres Beispiel für die Verwendung von Listen: Stell dir vor, du arbeitest in einem Unternehmen, in dem derzeit 6 Geschäfte geöffnet sind. Sie bitten dich, eine Anwendung zu schreiben, mit der die Informationen dieser Geschäften aus der Datenbank abgerufen werden. Nun, wenn du so begierig bist, würdest du ein Array verwenden und es auf 6-Geschäfte-Objekte beschränken, richtig, weil sie nur 6 Geschäfte haben. Die Probleme, die du nächstes Jahr haben wirst, wenn sie einen ihrer Läden schließen, weil ihre Programmierer nicht auf dem neuesten Stand waren würde nun sicherlich dazu beitragen, dass deine Anwendung zusammenbricht, nicht wahr?

Es ist besser, einfach zu lesenden und korrekt implementierten Code zu verwenden, wenn dies im Bereich Codeschnipsel u. Projekte enthalten sein soll. Ich weiß nicht einmal, warum es so schwer zu verstehen ist, dass jeder, der den Code von javaerd mit mehr als 6 Zahlen verwenden möchte, den Code von ihm überprüfen muss, ob er seine Arrays richtig verwendet hat, anstatt nur eine Liste zu verwenden, die flexibel ist und beliebig viele Zahlen enthalten kann, auch als generisch bekannt. Den Zweck von javaerd war es, dass sein Code im Bereich Codeschnipsel u. Projekte hinzugefügt wurde, dann hätte er ihn auch auf andere Fälle anwendbar gemacht, oder er hätte diesen Teil explizit aufgeschrieben. Das Gleiche gilt für seinen gelabelten Code. Niemand sollte dies in produktionsreifen Codes tun, geschweige denn in Tutorials, da es für einen neuen Programmierer, der sich dem Team anschließt, extrem schwierig ist, diesen Code zu durchlaufen. Du schreibst nicht die meiste Zeit nur Code für dich. Deshalb ist das verpönt. Es macht Dinge unlesbar, es macht Dinge schwerer als sie sein sollten. Ist das eine angemessene Erklärung oder soll ich es noch einmal durchgehen?

javaerd muss sein 'Code und deren Erklärung' in mehrere Teile aufteilen, um solche Ratschläge in Zukunft zu vermeiden. Er hat hier im Original-Beitrag etwas geschrieben, das völlig von der Rolle ist. Ich sehe hier nichts, woraus jeder lernen kann, außer wie man etwas absolut falsch macht.

Die Idee gefällt mir (aber bitte nicht mit einer externen Library).
Hallo mrBrown,

Grad mal eben bei Stackoverflow vorbeigeguckt? ;) Externe Lib für so ein Mini-Programm ist aber wirklich nicht nötig...
Erklärt mir, was daran falsch ist, wenn ihr eine externe Bibliothek verwendet, die den Test der Zeit bestanden hat, Open Source ist und sich in der aktiven Entwicklung befindet? Unter dieser Logik würde man nicht einmal die Standard Java Class Library verwenden... Warum überhaupt in Java zu schreiben? Warum gibt es Spring? Wenn ihr alles selbst schreiben möchtet, solltet ihr euch wahrscheinlich mit der BS-Entwicklung befassen, zur Hölle, vielleicht sogar TempleOS dabei helfen, seinen Zweck zu erreichen.

Wo siehst Du denn hier Speicherverluste?
Um mich mal selbst zu zitieren:
Falls du das anders siehst, dann "irrst du dich ernsthaft."
Es liegt kein Speicherverlust vor. Du hast Recht. Ich habe nie so viel gesagt. Ich sagte, javaerd sollte das v******** Ding zumachen. Wenn es ein Closable implementiert, schließt du es. Das ist doch gar nicht so schwer, oder? Wenn javaerd gemocht hätte, dass dies in ein Tutorial aufgenommen werde, dann hätte er das v******** Ding schließen sollen, auch wenn es nichts tut. Du bist einverstanden, dass man es schließen sollte oder du erklärst, warum du es nicht schließen würdest. Du denkst, ein Kind da draußen wird nicht sagen: Oh, wenn er es nicht schließt, muss es bedeuten, dass Scannerobjekte dann nicht geschlossen werden müssen. javaerd schreibt einen Tutorial. Er sollte die besten Vorgehensweisen implementieren.

Ich sehe hier nur, wie man es NICHT macht. Wenn javaerd ein Tutorial schreiben möchte, warum nicht ein Tutorial über Code-Labels für sich selbst schreiben (und warum er sie NICHT verwenden sollte)? Warum nicht den Arrays selbst ein Tutorial zu schreiben? Warum nicht ein Tutorial darüber zu schreiben, wie man einen Scanner benutzt? Warum nicht ein Tutorial darüber zu schreiben, wie man Listen benutzt? Warum nicht ein Tutorial darüber zu schreiben, wie man einen Zufallszahlengenerator ohne Wiederholung unter Verwendung der besten Codierungspraktiken erzeugt? Sicher musst du das jetzt sehen. javaerd sollte es richtig tun, so wie du weißt, wie es getan werden sollte. Hier schreiben wir über diese blöden Details, die allesamt zu einem Tutorial führen, das zu nichts anderem als schlechten Praktiken und schlecht geschriebenem Code führt, und du weißt es. Brauchtest du jemanden, der Absatz für Absatz für Absatz schreibt, um dir dies zu erklären? javaerd musste/muss sich (noch) mit den möglichen Abstürzen seiner Anwendung befassen. Ist das ein richtiger Code und deren Erklärung? Wie schwer soll ich auf dich runterkommen?

Wenn man wirklich was Ausdrucksstärkeres will, bieten sich statt Listen eher SortedSets an, die sind immer Sortiert und verhindern direkt Dublikate - genau das, was hier ja benötigt wird.
^ Das hier zeigt mir zumindest, wie man es richtig macht.


Grüße
 
Ein weiteres Beispiel für die Verwendung von Listen: Stell dir vor, du arbeitest in einem Unternehmen, in dem derzeit 6 Geschäfte geöffnet sind. Sie bitten dich, eine Anwendung zu schreiben, mit der die Informationen dieser Geschäften aus der Datenbank abgerufen werden. Nun, wenn du so begierig bist, würdest du ein Array verwenden und es auf 6-Geschäfte-Objekte beschränken, richtig, weil sie nur 6 Geschäfte haben. Die Probleme, die du nächstes Jahr haben wirst, wenn sie einen ihrer Läden schließen, weil ihre Programmierer nicht auf dem neuesten Stand waren würde nun sicherlich dazu beitragen, dass deine Anwendung zusammenbricht, nicht wahr?
Also das Beispiel ist so nicht korrekt/einleuchtend. Natürlich ist es ganz unproblematisch, da Arrays zu verwenden, da die Information sehr statisch ist. Wenn Du extrem viele Zugriffe hast, dann kannst Du Dir den Overhead sparen, denn z.B. eine Hash Lösung mit sich bringen würde. Die Wahl der Datenstrukturen ergibt sich ja vor allem über die Zugriffe und die daraus resultierenden Anforderungen.

Um an dem Beispiel herum zu spinnen: wenn ich Daten lese, dann kann ich ja erst ermitteln, wie viele Elemente ich brauche. Und wenn sich die Anzahl dann doch einmal ändert, dann erzeuge ich ein neues Array mit der neuen Größe und kopiere einmal die Elemente....

Erklärt mir, was daran falsch ist, wenn ihr eine externe Bibliothek verwendet, die den Test der Zeit bestanden hat, Open Source ist und sich in der aktiven Entwicklung befindet? Unter dieser Logik würde man nicht einmal die Standard Java Class Library verwenden... Warum überhaupt in Java zu schreiben? Warum gibt es Spring? Wenn ihr alles selbst schreiben möchtet, solltet ihr euch wahrscheinlich mit der BS-Entwicklung befassen, zur Hölle, vielleicht sogar TempleOS dabei helfen, seinen Zweck zu erreichen.
Es geht hier doch einfach um eine Minimierung von Abhängigkeiten. Die Standard Class Library ist keine externe Abhängigkeit. Ebenso ist es keine externe Abhängigkeit, wenn auch noch ein anderer Kollege Code beisteuert.

Ich finde es immer wieder interessant, wie Entwickler einfach so irgendwelche Libraries hinzu nehmen. Und das, wo die meisten noch nicht einmal die Lizenzbedingungen gelesen haben. Kommt ja einfach über Maven Central.... Sorry, aber das geht nicht ganz so einfach. Da muss man sich schon im Detail mit beschäftigen! Und die Konsequenzen muss man tragen. Das ist aber eine Entscheidung, die i.d.R. eben nicht vom Entwickler zu fällen ist.

Daher stimme ich dem zu: Wer ohne wirklichen Grund externe Abhängigkeiten einbringt, der macht einen klaren Fehler. Das mag bei irgendwelchen Pipifax Projekten in Schule und Studium gehen, aber in großen Projekten ist das ein no go.
Es liegt kein Speicherverlust vor. Du hast Recht. Ich habe nie so viel gesagt. Ich sagte, javaerd sollte das v******** Ding zumachen. Wenn es ein Closable implementiert, schließt du es. Das ist doch gar nicht so schwer, oder? Wenn javaerd gemocht hätte, dass dies in ein Tutorial aufgenommen werde, dann hätte er das v******** Ding schließen sollen, auch wenn es nichts tut. Du bist einverstanden, dass man es schließen sollte oder du erklärst, warum du es nicht schließen würdest. Du denkst, ein Kind da draußen wird nicht sagen: Oh, wenn er es nicht schließt, muss es bedeuten, dass Scannerobjekte dann nicht geschlossen werden müssen. javaerd schreibt einen Tutorial. Er sollte die besten Vorgehensweisen implementieren.
Also ich habe da eine komplett andere Sichtweise drauf!

Wenn jemand ein Tutorial schreibt, dann setzt er sich klare Prioritäten und muss Dinge abwägen.
- Wenn ein Tutorial ein Thema nicht behandelt, dann behandelt es dieses Thema nicht. Man überlegt sich eine Aussage und die wird dann möglichst verständlich beschrieben. (Typisches Beispiel: Ein komplexer Sachverhalt wird stark vereinfacht dargestellt. Dann ist die Darstellung ggf sogar schlicht falsch, weil eben gewisse Dinge einfach weggelassen wurden!)
- Externe Library in einem Anfänger Tutorial ist auch extrem daneben: Ein Anfänger will Deinen Code mal eben kopieren und Dein Code funktioniert für ihn einfach nicht.

Aber natürlich hast Du Recht: Ich sehe dieses AutoClosable ebenso wie das Disposable bei .Net: Es hat geschlossen zu werden. Daher ist das entweder in einem try with ressources oder wenn es gespeichert wird in einer Instanzvariable, dann wird die Klasse eben auch AutoClosable implementieren und die Problematik wird da dann weiter gegeben.

Und die Lösung hier in meinen Augen relativ einfach: Ich setze einfach ein public final static scanner inputScanner = new Scanner(System.in); und dann wird es genau einmal erstellt und bleibt über die ganze Laufzeit und wird eben nie geschlossen.
(Und Schreibweise hier angepasst an System.in, denn es ist hier nicht eine einfache Kontante für ein Literal... Also ähnlich wie System.in)
==> Kurz und schmerzlos für ein Tutorial. In einem wirklichen Projekt würde ich mir das aber auch noch überlegen, wie ich es da machen würde. Wäre aber wohl vom Prinzip ähnlich. Wobei ich da ein nicht schließbaren System.in stream auch vorstellen könnte, aber dann hätte ich regelmäßig doppelten Code in Form von try (Scanner in = new Scanner(SomeClass.in)){, so dass ich da dann wohl bei dem statischen Scanner Objekt bleiben würde.
 
Erklärt mir, was daran falsch ist, wenn ihr eine externe Bibliothek verwendet, die den Test der Zeit bestanden hat, Open Source ist und sich in der aktiven Entwicklung befindet?
a) Abhängigkeiten sind zu minimieren
b) die Lib enthält mehr als man braucht
c) viele Libs sind von wieder anderen Libs abhängig
d) je mehr Libs, desto höher das Risiko von Konflikten
e) nicht jede Lib erfüllt die Voraussetzungen, um im Unternehmen verwendet werden zu können
f) jede Lib birgt ein rechtliches Risiko

Und den ganzen Spaß, nur damit man sich
Java:
public class NonClosingInputStream extends FilterInputStream {
    public NonClosingInputStream(InputStream delegate) { super(delegate); }
    public void close() {}
}
spart?
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben