Wert am nächsten zur vollen Sekunde

Ich denke, eine Schwierigkeit könnte sein, dass/wenn du am Anfang nicht weißt, wie viele Zeilen in der Datei stehen (und da du da eine while-Schleife hast, kannst du da wohl nicht sicher sein).

Da wäre es vermutlich am einfachsten, die Daten nicht in einem Array zu speichern, sondern in einer List<Double>:

import java.util.ArrayList;
import java.util.List;


public class Temp
{
    public static void main(String[] args)
    {
        DateiInput leser = new DateiInput("A05_INP_Sensordaten.csv");
        String Zeile = null;
        double[] Maxwert = new double[3];
        double[] Minwert = { 1, 1, 1 };
        double Wert;
        
        List<Double> werte = new ArrayList<Double>();
        
        // Spaltennamen ignorieren
        leser.leseZeile();
        while ((Zeile = leser.leseZeile()) != null)
        {
            String[] Wertefeld = Zeile.split(";");
            
            Double wert = Double.parseDouble(Wertefeld[18]);
            werte.add(wert);
        }
        
        // Verwenden:
        for (int i=0; i<werte.size(); i++)
        {
            System.out.println("Der "+i+". Wert is "+werte.get(i));
        }
    }
}

Damit kann man dann rumrechnen (wenn man will, kann man die Liste dann auch in einen Array konvertieren, aber das sollte nicht “notwendig” sein…)

Mal so als Beispiel, wie man das angehen könnte. Die verschiedenen Problemchen dabei habe ich in verschiedene Klassen zerlegt. Vielleicht mag es helfen:


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class FindNearestTimesToFullSeconds {

    private static final Data NO_DATA_FOUND = new Data(-1.1, -1, -1);

    private List<Data> dataSets;

    public void work(List<Data> dataSets) {
        this.dataSets = dataSets;
        List<Integer> fullSeconds = createFullSeconds();
        List<Data> nearestDataSets = createNearestDataSets(fullSeconds);
        printNearest(nearestDataSets);
    }

    private List<Integer> createFullSeconds() {
        List<Double> allSeconds = generateAllSeconds();
        int minSecond = findLowerBorder(allSeconds);
        int maxSecond = findUpperBorder(allSeconds);

        List<Integer> fullSeconds = new ArrayList<>();
        for (int fullSecond = minSecond; fullSecond <= maxSecond; ++fullSecond) {
            fullSeconds.add(fullSecond);
        }

        return fullSeconds;
    }

    private List<Double> generateAllSeconds() {
        List<Double> allSeconds = new ArrayList<>();
        for (Data data :dataSets) {
            allSeconds.add(data.getTime());
        }
        return allSeconds;
    }

    private int findLowerBorder(List<Double> allSeconds) {
        if (allSeconds.isEmpty()) {
            return 0;
        }
        double minTime = Collections.min(allSeconds);
        return (int) Math.floor(minTime);
    }

    private int findUpperBorder(List<Double> allSeconds) {
        if (allSeconds.isEmpty()) {
            return 0;
        }
        double maxTime = Collections.max(allSeconds);
        return (int) Math.ceil(maxTime);
    }

    private List<Data> createNearestDataSets(List<Integer> fullSeconds) {
        List<Data> nearestDataSets = new ArrayList<>();

        for (int fullSecond : fullSeconds) {
            double fullSecondDouble = fullSecond;
            double minDistance = Double.MAX_VALUE;
            Data minDistanceData = NO_DATA_FOUND;
            for (Data data : dataSets) {
                double distance = Math.abs(data.getTime() - fullSecondDouble);
                if (minDistance > distance) {
                    minDistance = distance;
                    minDistanceData = data;
                }
            }
            if (NO_DATA_FOUND == minDistanceData) {
                throw new RuntimeException("no min value found");
            }
            nearestDataSets.add(minDistanceData);
            System.out.println("Volle Sekunde : " + fullSecond + " -> " + minDistanceData);
        }

        return nearestDataSets;
    }

    private void printNearest(List<Data> nearestDataSets) {
        System.out.println("Nächste Datenobjekte:");
        for (Data data : nearestDataSets) {
            System.out.println(data);
        }
    }


    public static void main(String[] args) {
        List<String> lines = readFile("c:/temp/sekundendaten.txt");
        printLines(lines);
        lines.remove(0); // Titelzeile entfernen

        CreateLineObjects create = new CreateLineObjects();
        List<Data> dataSets = create.create(lines);
        printDataSets(dataSets);

        FindNearestTimesToFullSeconds find = new FindNearestTimesToFullSeconds();
        find.work(dataSets);
    }

    private static List<String> readFile(String filename) {
        ReadFile reader = new ReadFile(filename);
        List<String> list = reader.read();
        reader.close();
        return list;
    }

    private static void printLines(List<String> lines) {
        System.out.println("Eingelesene Zeilen:");
        for (String line : lines) {
            System.out.println(line);
        }
    }

    private static void printDataSets(List<Data> dataSets) {
        System.out.println("Eingelesene Daten-Objekte:");
        for (Data dataSet : dataSets) {
            System.out.println(dataSet);
        }
    }

}

class ReadFile {

    private static final String CHAR_SET = "ISO-8859-1";
    private final String filename;
    private final LineNumberReader reader;

    public ReadFile(String filename) {
        this.filename = filename;
        reader = openReader();
    }

    public List<String> read() {
        List<String> list = new ArrayList<>();

        String line = readNextLine();
        while (line != null) {
            list.add(line);
            line = readNextLine();
        }

        return list;
    }

    private String readNextLine() {
        try {
            return reader.readLine();
        }
        catch (IOException e) {
            throw new RuntimeException("Es trat ein Fehler beim Einlesen der nächsten Zeile "
                    + "aus der Datei '" + filename + "' auf. (" + e.getMessage() + ")");
        }
    }

    private LineNumberReader openReader() {
        try {
            return tryToOpenReader();
        }
        catch (FileNotFoundException e) {
            throw new RuntimeException("Die Eingabedatei '" + filename
                    + "' wurde nicht gefunden. (" + e.getMessage() + ")");
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Bei der Erzeugung des "
                    + "InputStreamReaders für die Eingabedatei '" + filename
                    + "' wurde eine nicht unterstützte Kodierung verwendet. (" + e.getMessage()
                    + ")");
        }
    }

    private LineNumberReader tryToOpenReader() throws UnsupportedEncodingException,
            FileNotFoundException {
        InputStream inputStream = new FileInputStream(filename);
        InputStreamReader reader = new InputStreamReader(inputStream, CHAR_SET);
        return new LineNumberReader(reader);
    }

    public void close() {
        try {
            reader.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

}

class Data {
    private final double time;
    private final int valueA;
    private final int valueB;
    public Data(double time, int valueA, int valueB) {
        this.time = time;
        this.valueA = valueA;
        this.valueB = valueB;
    }
    public double getTime() {
        return time;
    }
    public int getValueA() {
        return valueA;
    }
    public int getValueB() {
        return valueB;
    }
    @Override
    public String toString() {
        return "Data [time=" + time + ", valueA=" + valueA + ", valueB=" + valueB + "]";
    }
}

class CreateLineObjects {

    public List<Data> create(List<String> lines) {
        List<Data> list = new ArrayList<>();
        for (String line : lines) {
            Data data = createDataFromLine(line);
            list.add(data);
        }

        return list;
    }

    private Data createDataFromLine(String line) {
        int expectedSize = 3;
        List<String> values = splitBy(line, "	");
        if (values.size() != expectedSize) {
            throw new RuntimeException("Eine Zeile lässt sich nicht in " + expectedSize
                    + " Teile teilen, sondern in " + values.size() + "!
	line = '" + line + "'");
        }
        double seconds = parseDoubleValue(values.get(0));
        int valueA = parseIntValue(values.get(1));
        int valueB = parseIntValue(values.get(1));
        return new Data(seconds, valueA, valueB);
    }

    private List<String> splitBy(String input, String regex) {
        List<String> list = new ArrayList<>();
        list.addAll(Arrays.asList(input.split(regex, -1)));
        return list;
    }

    private double parseDoubleValue(String stringValue) {
        try {
            return Double.parseDouble(stringValue);
        }
        catch (NumberFormatException excpetion) {
            throw new RuntimeException("Die Zahl '" + stringValue + "' ließ sich nicht in einen "
                    + "double-Wert parsen!");
        }
    }

    private int parseIntValue(String stringValue) {
        try {
            return Integer.parseInt(stringValue);
        }
        catch (NumberFormatException excpetion) {
            throw new RuntimeException("Die Zahl '" + stringValue + "' ließ sich nicht in einen "
                    + "int-Wert parsen!");
        }
    }

}```

Die Eingabedatei c:/temp/sekundendaten.txt sieht so aus:


Zeit Messwert-A Messwert-B
0.002 15 27
3.223 12 556
3.998 9 523
4.001 10 231
4.002 12 23
4.003 14 22
5.002 19 28



Die Ausgabe so:


Eingelesene Zeilen:
Zeit Messwert-A Messwert-B
0.002 15 27
3.223 12 556
3.998 9 523
4.001 10 231
4.002 12 23
4.003 14 22
5.002 19 28
Eingelesene Daten-Objekte:
Data [time=0.002, valueA=15, valueB=15]
Data [time=3.223, valueA=12, valueB=12]
Data [time=3.998, valueA=9, valueB=9]
Data [time=4.001, valueA=10, valueB=10]
Data [time=4.002, valueA=12, valueB=12]
Data [time=4.003, valueA=14, valueB=14]
Data [time=5.002, valueA=19, valueB=19]
Volle Sekunde : 0 -> Data [time=0.002, valueA=15, valueB=15]
Volle Sekunde : 1 -> Data [time=0.002, valueA=15, valueB=15]
Volle Sekunde : 2 -> Data [time=3.223, valueA=12, valueB=12]
Volle Sekunde : 3 -> Data [time=3.223, valueA=12, valueB=12]
Volle Sekunde : 4 -> Data [time=4.001, valueA=10, valueB=10]
Volle Sekunde : 5 -> Data [time=5.002, valueA=19, valueB=19]
Volle Sekunde : 6 -> Data [time=5.002, valueA=19, valueB=19]
Nächste Datenobjekte:
Data [time=0.002, valueA=15, valueB=15]
Data [time=0.002, valueA=15, valueB=15]
Data [time=3.223, valueA=12, valueB=12]
Data [time=3.223, valueA=12, valueB=12]
Data [time=4.001, valueA=10, valueB=10]
Data [time=5.002, valueA=19, valueB=19]
Data [time=5.002, valueA=19, valueB=19]