AWT Ich verstehe die Fehlermeldung nicht. Was habe ich falsch gemacht?

Naja, wenn ich nochmal vor einem für mich unlösbarem Problem stehen sollte, eröffne ich einfach nen neuen Thread, dieser hier kann also gerne als abgeschlossen markiert werden 😀 Danke für die Hilfe von allen
 
Ja im Endeffekt ist es so. Ich bin mir nicht ganz sicher, ob ich dann 200 Schleifen ineinander laufen lassen muss, aber naja was tut man nicht alles einfach nur so xD

Nein, Du zählst einfach durch.

Mal ein Beispiel mit 3 Zeichen (A, B, C) je Stelle:

0 = A
1 = B
2 = C
3 = AA
4 = AB
5 = AC
6 = BA
7 = BB
8 = BC
9 = CA
10 = CB
11 = CC
12 = AAA
usw.
 
Java:
import java.util.Arrays;
import java.util.stream.Collectors;

public class Combination {
    private int[] digits;
    private int base;

    public Combination(int base) {
        this.base = base;
        digits = new int[1];
    }

    private void addDigit() {
        digits = new int[digits.length + 1];
    }

    public void increase() {
        boolean done = false;
        int i = digits.length - 1;
        while (!done && i >= 0) {
            digits[i] = (digits[i] + 1) % base;
            done = (digits[i] > 0);
            i--;
        }

        if (!done) {
            addDigit();
        }
    }

    public String map(char[] symbols) {
        return Arrays.stream(digits)
            .mapToObj(i -> Character.toString(symbols[i]))
            .collect(Collectors.joining());
    }

    public static void main(String[] args) {
        char[] symbols = new char[]{'A','B','C'};
        Combination c = new Combination(symbols.length);
        for (int i = 0; i < 13; i++) {
            System.out.println(c.map(symbols));
            c.increase();
        }
    }
}
 
Man kann also die Länge von Arrays noch im Nachhinein ändern? Das ist ja praktisch.

Leider kenne ich mich mit Java noch nicht genügend aus, um das Mappen zu verstehen, oder was der Punkt vor den Zeilen bewirkt. Das gleiche gilt für das collect. Da informier ich mich jetzt erstmal drüber
 
Nein, man kann die Länge von Arrays nicht ändern. In addDigit wird immer ein neues Array erstellt. Mehr muss an der Stelle nicht passieren, weil die Elemente eines int-Arrays automatisch mit 0 initialisiert werden - und nichts anderes brauchen wir an der Stelle.

Der Punkt vor den Zeilen ist einfach das Trennzeichen zwischen Klasse bzw. Objekt und Methodenaufrufen. Da in Java Leerzeichen, Tabulatoren und Zeilenumbrüche einen Befehl nicht beenden, kann man sie praktisch beliebig setzen.

Arrays ist eine Klasse, Arrays.stream(..) ruft die (statische) Methode stream() der Klasse Arrays auf. Die Methode liefert im konkreten Fall ein IntStream-Objekt zurück, dessen mapToObj-Methode aufgerufen wird. Diese Methode liefert - weil Character.toString() ein Objekt vom Typ String zurückliefert - ein Stream<String>-Objekt. Darauf wird die Methode collect aufgerufen.
 
Wie der Name schon sagt, sammelt collect() die Elemente des Streams. Genauer, werden die Elemente in einem veränderlichen Container gesammelt. Das Interessante dabei sind die verschiedenen Collectors.

Gehen wir mal von einer String-Liste List<String> list aus, dann bewirkt

Code:
return list.stream().collect(Collectors.joining(","));
das gleiche wie
Code:
StringBuilder b = new StringBuilder();
for (int i = 0, n = list.size(); i < n; i++) {
    String s = list.get(i);
    if (i > 0) {
        b.append(",");
    }
    b.append(s);
}
return b.toString();
Hier würde der StringBuilder den oben genannten, veränderlichen Container darstellen.

Möchte man z. B. die Liste nach Strings filtern, die weniger als 6 Zeichen lang sind und die gefilterten Strings in einer Liste haben:
Code:
List<String> filtered = list.stream().filter(s -> s.length() < 6).collect(Collectors.toList());
 
Aber warte mal, wenn der collector ein Komma zwischen die Chars setzt wäre das ja kontraproduktiv, weil ich dann die kommas im nachhinein wieder rauslöschen müsste :O
 
Dann nimm doch einfach einen anderen Collector. Wenn du am Ende wieder eine Liste haben willst nimm toList(), wenn du einen anderen Delimiter haben willst dann ersetzt das Komma in joining() mit einem Zeichen
 
Code (Java):
import java.util.Arrays;
import java.util.stream.Collectors;

public class Combination {
private int[] digits;
private int base;

public Combination(int base) {
this.base = base;
digits = new int[1];
}

private void addDigit() {
digits = new int[digits.length + 1];
}

public void increase() {
boolean done = false;
int i = digits.length - 1;
while (!done && i >= 0) {
digits[i] = (digits[i] + 1) % base;
done = (digits[i] > 0);
i--;
}

if (!done) {
addDigit();
}
}


1.
Combination gibt nichts zurück aber ist auch nicht void. Soll ich einen return eines int[] einfügen oder es zum public void umschalten?

2.
Java:
.mapToObj(i -> Character.toString(carray[i]))
// i cannot be resolved to a variable

mapToObj funktioniert demnach was ich gelesen habe nur mit einem Integerstream, aber hier soll ja mit Chars gearbeitet werden. Ich denke das deswegen der Code von .mapToObj auch nicht kompiliert werden kann. Ich habe zwar davon gehört, dass ein Stream aus Chars als IntStream weitergegeben wird, aber dann verstehe ich nicht, warum es sich nicht komplieren lässt.

3.
aus Combination in main
Combination c = new Combination(symbols.length);
lässt sich kein Array machen, falls du das hier vorhattest

4.
char[] symbols = new char[]{'A','B','C'};
habe ich rausgenommen und symbols durch carray in anderen funktionen ersetzt, da carray alle Zeichen enthält.

Ich arbeite jetzt zum ersten mal mit solchen Funktionen, berichtige mich gerne wenn du siehst, dass ich irgendwo falsch liege.
 
zu 1.: das ist der Konstruktor, der automatisch aufgerufen wird, wenn Du ein neues Combination-Objekt mittels new Combination(...) erstellst. Für den Konstruktor gibt man keinen Rückgabewert an.

zu 2.: Arrays.stream(digits) liefert einen IntStream, weil digits ein int-Array ist. Das i in mapToObject(i -> ...) kennzeichnet einen int-Wert aus dem Stream. Der Code wird übrigens einwandfrei übersetzt.

zu 3.:
lässt sich kein Array machen, falls du das hier vorhattest
Nein, das hatte ich nicht vor, wie kommst Du darauf?

zu 4.: ja, das Array symbols habe ich nur deswegen so gewählt. Es spielt keine Rolle, aus welchen Elementen Du die Kombinationen bildest - so lange die Anzahl der Elemente korrekt an den Konstruktor übergeben wird, passt das.
 
Zu Stellen 1-3, die können nicht 100% fehlerfrei sein, die geben in meiner IDE ne Fehlermeldung aus

Mit 3 meinte ich, dass das nicht richtig erkannt wird, bzw der Compiler Combination nicht akzeptiert. Genauso bei .mapToObj und 1
 
Eclipse Java EE IDE for Web Developers.

Version: Juno Release
Build id: 20120614-1722

(c) Copyright Eclipse contributors and others 2005, 2012. All rights reserved.
Visit http://www.eclipse.org/webtools


Übrigens, habe mal nur zum Spaß alle Kombinationen in ner Länge von 4 zusammenschreiben lassen und naja was soll ich sagen, die Datei ist schon 500MB groß und hat meinen PC für ein paar Sekunden zum einfrieren gebracht, in etwa das was ich erwartet habe...das Ding dabei ist, wenn das weiterhin so exponentiell mehr wird (was es definitiv wird), habe ich bei 6 kombinationslängen nicht genügend speicherplatz auf meiner Festplatte um die Kombis auch zu speichern lol. Kann man das auf nen Server mit Exabytes an Kapazität verschieben xD?

EDIT: Der Editor lädt seit ein paar Minuten schon die Datei, bis jetzt noch auf keine Rückmeldung

EDIT2: Editor ist abgeschmiert xD
 
Wen wundert es auch, immerhin hat die letzte Iteration eine Speichermenge von 96^200 bytes ~2*10^36 bytes
(alle anderen Iterationen vernachlässigend)
 
ok ich habe gerade nachgeguckt, das wären an die 2 Zettabytes und in etwa so viele Daten, wie es seit anbeginn der Computer gibt lol ich denke mal, ich implementiere eine funktion, die alle unbrauchbaren Zeilen direkt aussortiert. Kann man einen reader und writer gleichzeitig laufen lassen?
 
Java:
package de.writer.java;
import java.io.*;
public class Writepossibilities {

    private static final String FILENAME = "C:/Users/Cornelius/Desktop/writepossibilities.txt";
   
    public static void main(String[] args) throws IOException {
       
        char[] carray = new char[96];
        int carrayZähler= 0;
        int weitererCarrayZähler=0;
       
            for (char e ='a'; e <='z'; e++){
                carray[carrayZähler] = (char) e;
                carrayZähler++;
                carray[carrayZähler] = (char) (e-32) ;
                carrayZähler++;
            }
           
            char[] mitCarrayIntegrieren = "üÜöÖäÄ@€ |<>~*+'#.:]}ß?()/&%=$§\"!^°µ0123456789".toCharArray();
            for (int h = mitCarrayIntegrieren.length; h > 0; h--) {
                carray[96 - h] = mitCarrayIntegrieren[weitererCarrayZähler];
                weitererCarrayZähler++;
            }        
           
            try(FileWriter writer = new FileWriter(FILENAME)) {
                for(int i =0; i <carray.length; i++){
                    if(i!=0){
                    writer.write(System.getProperty("line.separator"));
                    }
                    writer.write(carray[i]);
                }
                for (int o=1; o <carray.length;o++){
                for(int i =0; i <carray.length; i++){
                    writer.write(System.getProperty("line.separator"));
                    writer.write(carray[o]);
                    writer.write(carray[i]);               
                }
                }
                for(int i2=0; i2 <carray.length;i2++){
                for(int i1=0; i1 <carray.length;i1++){
                for(int i =0; i <carray.length; i++){
                        writer.write(System.getProperty("line.separator"));
                        writer.write(carray[i]);
                        writer.write(carray[i1]);
                        writer.write(carray[i2]);
                }
                }
                }
                for(int i3=0; i3 <carray.length;i3++){
                for(int i2=0; i2 <carray.length;i2++){
                for(int i1=0; i1 <carray.length;i1++){
                for(int i =0; i <carray.length; i++){
                            writer.write(System.getProperty("line.separator"));
                            writer.write(carray[i]);
                            writer.write(carray[i1]);
                            writer.write(carray[i2]);
                            writer.write(carray[i3]);
                }
                }
                }
                }
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
           
            }
            System.out.println("Done!");
        }
    }


ich mein ja nur, das ist der aktuelle code. Wird nicht schwer sein z.B. alle Zeilen rauszufiltern, die nicht durch ein semicolon beendet werden oder noch offnen/zu viele schließende Klammern haben mit if conditions
 
Mein Fehler hab ne Klammer falsch gesetzt. Muss schon sagen, dass dein Code sehr elegant ist, aber leider ist mir da wieder die IDE im weg, weil ints immer nur begrenzt groß sein können, lassen sich auch nur begrenzt viele Kombis ausgeben. Leider sieht die IDE die Zahl 2,84*10^396 als zu groß an :/
EDIT und gleich nochmal ups Math.pow(96,200) wurde akzeptiert
 
Zuletzt bearbeitet:
Ja...ich weiß es ist viel. Deswegen will ich ja jetzt auch ein paar Filterfunktionen implementieren, damit es auf Billiarden Zeilen verkürzt wird(bis jetzt noch nichts implementiert weil ich bin müde, aber mache ich sobald ich wieder wacher bin). Mein Rechner hat nämlich nur noch 80gb auf der Platte frei
 
Muss schon sagen, dass dein Code sehr elegant ist, aber leider ist mir da wieder die IDE im weg, weil ints immer nur begrenzt groß sein können, lassen sich auch nur begrenzt viele Kombis ausgeben. Leider sieht die IDE die Zahl 2,84*10^396 als zu groß an :/
EDIT und gleich nochmal ups Math.pow(96,200) wurde akzeptiert

Gehts es um die for-Schleife in main? Die kannst Du doch problemlos ersetzen.

Combination speichert die Stellen der Zahl in einem int-Array (was schon Verschwendung ist; bei 96 Symbolen würde z. B. auch ein byte-Array reichen, aber das können wir mal vernachlässigen). Um 96^200 Kombinationen darzustellen, braucht es ein Array der Länge 200.

D. h. in Combination musst Du lediglich die Zahl der Stellen zurückgeben
Code:
    public int countDigits() {
        return digits.length;
    }

Und dann zählst Du in main() die Zahl so lange hoch, bis sie eine Länge von 201 erreicht hat:
Code:
    while (c.countDigits() < 201) {
            System.out.println(c.map(symbols));
            c.increase();
    }
 
Hmmm ich sitze jetzt wieder seit ein paar Stunden dran, soweit funktioniert der Code, ich kann ihn halt schlecht laufen lassen, weil der locker 10 Milliarden Jahre bräuchte um fertig zu werden...deswegen gucke ich gerade nach Lösungen, um den Fortschritt, den der gemacht hat zwischen zu speichern, vielleicht auch eine Unterstützung für mehrere Rechner gleichzeitig einzubauen...sodass auch trotz neustart von Windows nicht jedes mal eine neue Datei erstellt wird und der wieder anfängt alle Kombinationen von vorne durchzugehen...leider verliert man schnell den Überblick, wo im Code man so was einbauen könnte. Aber ich denke man könnte immerhin speichern bei welcher Kombinationslänge der sich befindet, die ruft der ja schon so oder so ab. Dann wäre nur das Problem, dass der Writer die Datei jedes mal löscht und eine neue erstellt, ist es möglich, den einfach in der gleichen Datei weiterschreiben zu lassen? Oder muss ich dass bei einem Neustart z.B. von Windows dann vom Programm in eine andere Datei verlagern, damit der diese Datei als eine Art zwischenspeicher nutzen kann?
EDIT: Das ganze über einen Cloud-synchronisierten Speicher, dann könnten auch 2 Rechner abwechselnd z.B. dran rechnen ^^ aber einfacher wärs natürlich, wenn ich den Progress, der der ausgeführte Task hat in einer Variable speichern könnte damit sie sogar parallel Aufgabenblöcke abarbeiten könnten...
 
In die gleiche Datei weiterzuschreiben, ist überhaupt kein Problem, dafür gibt es die "append" Option beim Erstellen des Writers.
Um den Status abzuspeichern (und wiederherzustellen), zerstückel die Schleifen. Hol dir die Variablen nach außen, damit du sie schon vorher initialisieren kannst. Das kann etwas tricky sein.
Ein Ansatz wäre vielleicht, dass alle Eigenschaften (Zähler, was auch immer) deines aktuellen Status Klassenvariablen sind. Dann serialisierst du die Klasse einfach (nach Xml, Json, was die am besten gefällt) und stellst sie beim nächsten Programmaufruf wieder her, lässt sie von der Stelle aus weiterarbeiten.
 
Ließen sich nicht auch die Statuszähler einfach so über einen weiteren writer in eine txt datei schreiben, die dann jedes mal am anfang des programms von einem reader ausgelesen würde um die startwerte der Zähler festzulegen? Oder muss das über xml/json laufen?
 
Ließen sich nicht auch die Statuszähler einfach so über einen weiteren writer in eine txt datei schreiben, die dann jedes mal am anfang des programms von einem reader ausgelesen würde um die startwerte der Zähler festzulegen? Oder muss das über xml/json laufen?

EDIT

Das ist der aktuelle code, oder ich sollte vielleicht besser sagen mihe7's Code
Java:
package de.besserer_writer.java;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Collectors;


public class Bessererwriter {
     private int[] digits;
     private int base;
     private static final String FILENAME = "D:/writepossibilities.txt";

        public Bessererwriter(int base) {
            this.base = base;
            digits = new int[1];
           
        }
       
        public int countDigits() {
            return digits.length;
        }
       
        private void addDigit() {
            digits = new int[digits.length + 1];
        }

        public void increase() {
            boolean done = false;
            int i = digits.length - 1;
            while (!done && i >= 0) {
                digits[i] = (digits[i] + 1) % base;
                done = (digits[i] > 0);
                i--;
            }

            if (!done) {
                addDigit();
            }
        }
       
        public String map(char[] symbols) {
            return Arrays.stream(digits)
                .mapToObj(i -> Character.toString(symbols[i]))
                .collect(Collectors.joining());
        }

        public static void main(String[] args) {
            char[] symbols = new char[96];
             int carrayZähler= 0;
             int weitererCarrayZähler=0;
           
                 for (char e ='a'; e <='z'; e++){
                     symbols[carrayZähler] = (char) e;
                     carrayZähler++;
                     symbols[carrayZähler] = (char) (e-32) ;
                     carrayZähler++;
                 }
               
                 char[] mitCarrayIntegrieren = "üÜöÖäÄ@€ |<>~*+'#.:]}ß?()/&%=$§\"!^°µ0123456789".toCharArray();
                 for (int h = mitCarrayIntegrieren.length; h > 0; h--) {
                     symbols[96 - h] = mitCarrayIntegrieren[weitererCarrayZähler];
                     weitererCarrayZähler++;
                 }       
            Bessererwriter c = new Bessererwriter(symbols.length);
                try(FileWriter writer = new FileWriter(FILENAME)) {
                    while (c.countDigits() < 201) {
                        System.out.println(c.map(symbols));
                        if(c.map(symbols).contains("(")) {
                            if(c.map(symbols).contains(")")) {
                                writer.write(c.map(symbols));
                                writer.write(System.getProperty("line.separator"));
                            }
                        }
                        c.increase();   
                    }
                   
                } catch (IOException e) {
                e.printStackTrace();
                }
                System.out.println("Done!");
            }
        }

Nur damit ich dich richtig verstehe. Die Codezeile
try(FileWriter writer = new FileWriter(FILENAME)) {
guckt, ob das Dokument, welches unter dem String FILENAME abgespeichert ist, ob es bereits existiert, wenn ja löscht es dieses und erstellt es dann erneut. Wo genau kann ich eine .append Methode unterbringen um dies zu unterbinden? Meines Wissens nach würde .append nur eine weitere Stelle zu symbols[] hinzufügen und so zu einer IndexOutOfBounds Exeption führen, insofern ich nicht die größe von symbols[] anpasse.
 
guckt, ob das Dokument, welches unter dem String FILENAME abgespeichert ist, ob es bereits existiert, wenn ja löscht es dieses und erstellt es dann erneut.
Die Datei wird überschrieben.

Wo genau kann ich eine .append Methode unterbringen um dies zu unterbinden?
Es geht nicht um eine Methode, sondern um einen Parameter im Konstruktor:

https://docs.oracle.com/javase/8/do...ter.html#FileWriter-java.lang.String-boolean-

Oder muss das über xml/json laufen?
Nö. Du kannst z. B. mit einem FileOutputStream die digits als Bytes rausschreiben und beim Start über einen FileInputStream wieder einlesen. Mit einem Shutdown-Hook kannst Du das Rausschreiben bis zum Abbruch mit Ctrl+C hinauszögern.
 
Ließen sich nicht auch die Statuszähler einfach so über einen weiteren writer in eine txt datei schreiben, die dann jedes mal am anfang des programms von einem reader ausgelesen würde um die startwerte der Zähler festzulegen? Oder muss das über xml/json laufen?
Natürlich, das geht problemlos. Mit Serialisierung geht halt einiges automatisch, wenn man's richtig macht.
 

Zurück
Oben