Mehrdimensionales float Array aus .txt-Datei einlesen?

natha

Mitglied
Guten Abend allerseits, 🙂


Zuerst mal ich bin ein absoluter Anfänger und hoffe sehr mir hilft hier jemand auf die Sprünge..
Mein Problem ist Ich möchte aus einer .txt Datei Koordinaten in Java einlesen als float Werte. Die .txt-Datei sieht im Prinzip so aus:


-0.68631 8.66286
1.01127 4.68321
-0.90299 6.73932
2.37965 4.54436
-1.62630 2.68927

... (etwa 300 Zeilen)
Jede Zeile enthält jeweils die zusammengehörigen x und y Koordinaten.
Ich brauche die eingelesenen Werte nicht als String sondern als float um weiter damit arbeiten zu können (Mittelwertberechnung, Darstellung, Clustering, K-Means,...)


Leider habe ich keinen Ansatz, ich habe zwar gesucht, finde aber nur Ansätze zum Einlesen in Strings. Ich möchte aber gerne ein zweidimensionales Array vom Typ float. Ich glaube dafür brauche ich ein FileInputStream("daten.txt");

Aber wie genau kann ich die Koordinaten als mehrdimensionales Array[xWert][yWert] zeilenweise aus der Datei einlesen?
Oder muss ich das dann doch erstmal als String einlesen, da man dann readLine() verwenden kann? Aber dann wüsste ich auch nicht wie man die String-Zeilen wiederum als zwei float Koordinaten in ein Array bekommt?


Ich hoffe mir kann hier jemand helfen, ich habe so gar keinen Plan ;(

LG
natha
 
Danke für die schnelle Antwort!
Ich hatte zwar gehofft, dass es mit weniger Umwegen möglich ist, aber dann mach ich das eben so 🙂

Wie genau splitte ich denn einen String dementsprechend?
Ich hatte es so versucht:

Code:
[COLOR=#a9a9a9]String[] spalten = new String[2] ;
String[] zeilen = new String[300];



public float[] read() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("data.txt"));
String line;


int i = 0;
while ((line = br.readLine()) != null) {
zeilen[i] = line;

System.out.println(zeilen[i]); 
i++;

}

br.close();

// This is for resize the data array (and data.length reflect new size)[/COLOR][COLOR=#d3d3d3]
[/COLOR]
String[] zeilenNew = new String[i];
System.arraycopy(zeilen, 0, zeilenNew, 0, i);
zeilen = zeilenNew;


[COLOR=#ff0000]for (i=0; i < zeilen.length; i++){
        
String[] Werte = new String [600]; 
        Werte = zeilenNew[i].split("\\s+");

System.out.println(Werte[i]);    [/COLOR]


[COLOR=#a9a9a9]/*...
float x[] = new float [300];
float y[] = new float [300];

???


return x;
return y;
*/[/COLOR]

Ausgegeben hat er mir:

0.83686
7.40962
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2

die Daten lauteten aber:
0.83686 2.13636
-1.41366 7.40962
1.15521 5.09962
...


Kann also so noch nicht stimmen..

Ich möchte jetzt gerne die jeweils ersten Zahlen je Zeile in ein Array namens x[] und die zweiten Zahlen in ein y[] speichern.
Wie bekomme ich das hin?


Danke schonmal
 
Zuletzt bearbeitet:
Java:
public static void main(String[] args) {
		 
		String[] data = {"0.83686 2.13636", "-1.41366 7.40962", "1.15521 5.09962"};
		float[]x = new float[3];
		float[]y = new float[3];
		
		
		for (int i = 0; i < data.length; i++) {
			String s = data[i];
			String[]temp = s.split("\\s");

			String number1 = temp[0];
			String number2 = temp[1];
			
			x[i] = Float.parseFloat(number1);
			y[i] = Float.parseFloat(number2);
			
		}
		
		System.out.println("X-Werte:");
		for(float f : x){
			System.out.println(f);
		}
		
		System.out.println("\nY-Werte:");
		for(float f : y){
			System.out.println(f);
		}		
	}

Ausgabe:
X-Werte:
0.83686
-1.41366
1.15521

Y-Werte:
2.13636
7.40962
5.09962
 
@TO
Hier ist ein Auszug aus deinem Code:
Java:
for (i=0; i < zeilen.length; i++){
    String[] Werte = new String [600]; 
    Werte = zeilenNew[i].split("\\s+");
    System.out.println(Werte[i]);    
}
Die Schleife ist Käse. i ist der Zeilenindex, aber innerhalb deiner Schleife verwendest du ihn als "Zellenindex", um aus der aktuellen Zeile Werte auszulesen.
In der 1. Zeile bekommst du deshalb den ersten (x) Wert ausgegeben, in der 2. Zeile den y-Wert, und in der 3. Zeile eine Excepion, weil es in der Zeile keinen 3. Wert gibt.
 
Vielen vielen Dank Saheeda, da wäre ich ohne deine Hilfe nicht drauf gekommen!^^
Wenn ich das jetzt sehe, ist das natürlich total einleuchtend.
Auch Danke an Harry Kane für den Hinweis, jetzt verstehe Ich was da schiefgelaufen ist, da habe ich wohl nicht mitgedacht..

Ich hab es jetzt hinbekommen, dass die Werte direkt aus der Textdatei gelesen werden und schön geordnet als float x/y-Koordinaten abrufbar sind. Jetzt kann ich endlich anfangen, damit zu arbeiten..

Einen schönen Abend euch noch!
 
Oh verdammt.. zu früh gefreut :-(

Ich hab ganz übersehen, dass ich die Daten für die Bibliothek, mit der ich arbeiten will als HashSet brauche und nicht als Array.
Ich bitte also nochmals um Hilfe, denn mit Generics kenne ich mich überhaupt nicht aus..

Ich muss jetzt also entweder nochmal direkt die .txt Datei in ein <Float>HashSet einlesen und dann nochmals x und y Koordinaten trennen
oder die beiden float[] x und float[] y irgendwie in ein HashSet einlesen/umwandeln(?)

Zweiteres wäre mir lieber, allerdings weiß ich nicht, ob das überhaupt so einfach möglich ist? Leider finde ich dazu nichts..
Ich hatte es schon versucht über xData.add(klassenname.leseX()); aber natürlich macht er das nicht, weil er ein float möchte und kein float[]

Wäre sehr schön, wenn ihr mir nochmal weiterhelfen könntet.
 
Wenn man Saheedas Lösung hernimmt:
Ändere die Zeile, in der die float-Arrays initialisiert werden in:
Java:
Set<Float> xSet = new HashSet<Float>();
Bei der Zuweisung des Wertes an der Stelle i:
Java:
xSet.add(Float.valueOf(number1));

Oder falls du deine zwei Arrays schon hast, dann kannst du sie gleich dem Konstruktor übergeben:
Java:
Set<Float> xSet = new HashSet<Float>(Arrays.asList(xValues));
 
Danke Flown, aber so ganz bekomme ich das noch nicht hin..

Ich hatte zum erzeugen der Arrays eine Klasse "Data" mit den Methoden:

Code:
    public static void main(String[] args) throws IOException {
        
        leseX();
        leseY();
    }
    
    public static float[] leseX() throws IOException{
        
         String[] spalten = new String[2] ;
         String[] zeilen = new String[300];
          
         BufferedReader br = new BufferedReader(new FileReader("data.txt"));
         String line;
              int i = 0;
            while ((line = br.readLine()) != null) {
                zeilen[i] = line;


             //   System.out.println(zeilen[i]); 
                i++;
            }
      
         br.close();
        
         String[] data = zeilen;
         float[]x = new float[300];
         float[]y = new float[300];
     
         for ( i = 0; i < data.length; i++) {
            String s = data[i];
            String[]coords = s.split("\\s");
     
            String number1 = coords[0];
            String number2 = coords[1];
     
            x[i] = Float.parseFloat(number1);
            y[i] = Float.parseFloat(number2);
        }
        
         return x;
    }

//(gleiches für leseY();)

Damit hab ich also schon die float[] Arrays für x und y.
Diese muss ich ja nun stattdessen in ein HashSet adden, um in der Klasse "Chart" diese Werte verwenden zu können.
Die Klasse "Chart" gehört zu einer Bibliothek und die Methode, für die ich die Werte brauche sieht so aus:

Code:
@Override
  public Chart getChart() {
 
    Set<Float> xData = new HashSet<Float>();
    Set<Float> yData = new HashSet<Float>();
    
    int size = 1000;
    for (int i = 0; i < size; i++) {
  
      xData.add(... );
      yData.add(... );       
           
    }

Ich bin mir nicht sicher, wie ich deine Code Vorschläge hier umsetze, wenn ich es versuche, funktioniert das nicht, wahrscheinlich mache ich das an der falschen Stelle.. und wie ist das mit solchen HashSets und Referenzen? Ich hab ja zwei Klassen, ist es sinnvoller die HashSets in der Klasse "Data" oder in der Klasse "Chart" zu initialisieren?

Ich hatte es zum Beispiel versuch in der Klasse "Chart" mit

Set<Float> xData = new HashSet<Float>(Arrays.asList(Data.leseX()));

aber das funktioniert nicht

Ich wäre dankbar für einen Tipp.
 
Zuletzt bearbeitet:
Eins ist mir noch immer nicht klar was du machen willst. Du lest x/y-Paare ein, aber du trennst sie. Des Weiteren willst du diese in ein Set haben (Duplikate werden dabei verhindert).

Also ich perönlich würde wenn dann schon eine Liste nehmen.

Auch solltest du das nur einmal einlesen und nicht zweimal:

Eine Tupelklasse als Wrapper für beide Ergebnisse:
Java:
class Coordinates {
  private final List<Float> x, y;

  public Coordinates(List<Float> x, List<Float> y) {
    this.x = x;
    this.y = y;
  }

  public List<Float> getX() {
    return Collections.unmodifiableList(x);
  }

  public List<Float> getY() {
    return Collections.unmodifiableList(y);
  }
}

Deine Methode:
Java:
public Coordinates readCoordinates(String path) throws IOException {
  List<Float> x = new ArrayList<>();
  List<Float> y = new ArrayList<>();
  try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
    for (String line = reader.readLine(); line != null; line = reader.readLine()) {
      final String[] coords = line.split("\\s+");
      x.add(Float.valueOf(coords[0]));
      y.add(Float.valueOf(coords[1]));
    }
  }
  return new Coordinates(x, y);
}
 
Durch das Einlesen in ein Array, was ich ja unnötigerweise schon gemacht hab, sind jetzt natürlich Umwege entstanden..

Kurz gesagt, eigentlich muss ich nur den Datensatz aus der .txt Datei einlesen und sie dann mit der Chart Klasse visualisieren. Diese Klasse ist eine Bibliothek, die dann ein Koordinatensystem anzeigt. Dazu benötige ich die Methode, die ich oben hingeschrieben habe, welche nur über die HashSets funktioniert. Deshalb darf ich nicht viel an der Methode verändern, darum kann ich auch nicht einfach Lists verwenden, muss mich eben an die Vorgaben halten. Ich hab schon versucht sie so umzuschreiben, dass sie die Werte aus den float Arrays ausgibt, aber das geht nicht. Die Bibliothek muss schon so beibehalten werden, damit die Visualisierung funktioniert.

Deshalb muss ich jetzt die x Werte ins xData HashSet und die y Werte ins yData HashSet kriegen.

Code:
public Chart getChart() {
 
    Set<Float> xData = new HashSet<Float>();
    Set<Float> yData = new HashSet<Float>();
    
    int size = 1000;
    for (int i = 0; i < size; i++) {
  
      xData.add(... );
      yData.add(... );       
           
    }

Da ich die Werte ja schon als getrennte Arrays hatte, hatte ich gehofft, dass man einfach das float[]x in das xData und das float[]y in das yData Hashset übertragen kann. Aber das scheint wohl nicht zu gehen, ich hab schon alles mögliche versucht.

Leider hab ich mir die Bibliothek vorher nicht angeschaut, darum hab ich nicht bemerkt, dass ich ein HashSet brauche und kein Array.

Gibt es denn etwas, was ich da jetzt tun kann, so wie der Code jetzt aussieht, oder muss ich komplett von vorn anfangen und die .txt Datei direkt in ein HashSet einlesen und wiederum x und y trennen? Wie gesagt, ich kenne mich überhaupt nicht mit HashSets aus und weiß echt nicht weiter.
 
Zuletzt bearbeitet:
Du hast schon alles versucht?

Dann probier mal das Einlesen von mir und dann:
Java:
Coordinates cords = readCoordinates(/* Path to file */);
xData.addAll(cords.getX());
yData.addAll(cords.getY());
 
Zuletzt bearbeitet:
Ich probiere deine Vorschläge mit der Klasse Coordinates nochmal,
ich hab nur noch eine wahrscheinlich dumme Frage..
bei

Coordinates cords = readCoordinates(
/* Path to file */)

und bei

public Coordinates readCoordinates(
String path) throws IOException {


Was für einen Pfad soll ich da angeben zu welchem File?
 
Ok das war wirklich eine dumme Frage, ich seh jetzt erst, dass das String path eine Variable ist. peinlich.. und ich find den Edit-button nicht mehr 😳

Allerdings ist mir das path to file noch nicht ganz klar.. da müsste doch nach meinem Verständnis die Klasse rein, auf die verwiesen wird? Also genauer gesagt:

Coordinates cords = readCoordinates(Coordinates.?);
aber welches Element der Klasse muss ich hier genau adressieren? Wiederum readCoordinates()? coords? Nein, geht nicht.
Aber es müssen ja die Koordinaten adressiert werden..
Ich bin zu doof -.-
 
Hmmm jetzt wird es mühselig und ich versuche wirklich dir zu helfen. Aber Grundlagen würden dir nicht schaden.

Der Parameter für die Methode ist ein String und gibt den Pfad zu deiner Datei an:

Ein Pfad ist wie im Explorer oder Shell: Bei Windows: "C:\Ordner\text.txt" oder Unix: "/home/ordner/text.txt"

Java:
Coordinates cords = readCoordinates("data.txt");
 
Achso ich weiß warum das alles nicht geht, ich dachte das


  1. Coordinates cords = readCoordinates(/* Path to file */);
  2. xData.addAll(cords.getX());
  3. yData.addAll(cords.getY());

    soll in die andere Klasse, aber das gehört ja noch zur Klasse Coordinates^^

Danke. das hatte ich auch zuerst, aber als es nicht ging, dachte ich da liegt der Fehler am path.. Danke für deine Hilfe
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben