In this example we will be using Bitcoin data in CSV (comma-separated values file) which we will custom parse and load in our application. Then user have to provide date in format year-month-day (yyyy-MM-dd) and the program will print the highest BTC (Bitcoin) price and the lowest BTC (Bitcoin) price in United States dollars.
In this program there are a lot of actions so lets unfold them. First you need to have data. I download mine from https://finance.yahoo.com/quote/BTC-USD/history/ where I get the history of the Bitcoin for the last year in CSV format.
I also will attach my file in case you just want to download it:
CSV file is a comma-separated values file but if we open it with tool like Microsoft Excel or LibreOffice Calc we will see that the file is recognized and separated by rows and columns. In this case first row is header row and contain the names of the column:
Date | Open | High | Low | Close | Adj Close | Volume |
2021-10-31 | 61850.488281 | 62406.171875 | 60074.328125 | 61318.957031 | 61318.957031 | 32241199927 |
2021-11-01 | 61320.449219 | 62419.003906 | 59695.183594 | 61004.40625 | 61004.40625 | 36150572843 |
2021-11-02 | 60963.253906 | 64242.792969 | 60673.054688 | 63226.402344 | 63226.402344 | 37746665647 |
2021-11-03 | 63254.335938 | 63516.9375 | 61184.238281 | 62970.046875 | 62970.046875 | 36124731509 |
2021-11-04 | 62941.804688 | 63123.289063 | 60799.664063 | 61452.230469 | 61452.230469 | 32615846901 |
2021-11-05 | 61460.078125 | 62541.46875 | 60844.609375 | 61125.675781 | 61125.675781 | 30605102446 |
2021-11-06 | 61068.875 | 61590.683594 | 60163.78125 | 61527.480469 | 61527.480469 | 29094934221 |
So now lets see see how the program is working:
- It will ask user to give path to the file.
- The program will check if the file really exist. If not it will give a error message and it will stop.
- Then data will be read from the CSV file use Files.newBufferedReader(path).
- Inside we use reader.lines() to read the lines skip(1) to skip the first line because first line is the header and we don’t need to parse it.
- Then use map(MainReadCSV::parseStringToDataRow) to actually map the result from String lines of the file to the record DataRow(LocalDate date, BigDecimal high, BigDecimal low) and finally return new list.
- Let’s look closer into method parseStringToDataRow. Inside the line (which is string) will be split by “,” into array of string and then knowing the index of the columns we can get each data separately.
- From all of the column only first column “Date”, third column “High” and forth column “Low” (look at the document structure above) are interesting for us. So from this strings we create LocalDate (with format yyyy-MM-dd ), BigDecimal and BigDecimal (Rounding BigDecimal values with 2 Decimal Places)
- Normally data is sorted in this file but just to be sure lets sorting it by date
- The program find and it will show to the user which is the earliest and latest date
- After the data is ready the program will ask the user to give a date in a same format yyyy-MM-dd
- The program will check if user input date is between the first date in the file and the last date
- In the end we are filtering for this date with Predicate.
- If we find the record we display the Bitcoin highest and lowest price for that day.
- If there is missing data which we require then error message will print: No data was found in the file for this date!
import java.io.BufferedReader; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.Scanner; public class MainReadCSV { private record DataRow(LocalDate date, BigDecimal high, BigDecimal low) { } private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static void main(String[] args) { // Use 'try' to close Scanner and release taken resources. // Connect the scanner to System.in (keyboard) try (Scanner in = new Scanner(System.in)) { String initMsg = """ Please enter the path to the file and please don't leave empty spaces else they need to be escaped. 1. If you are using Windows then make sure you path looks in format: c:\\folder\\BTC-USD.csv 2. If you are using Linux/Unix then the format: /home/username/BTC-USD.csv fileInput: """; System.out.print(initMsg); String filePathString = in.nextLine(); // check if the file exist: Path path = Paths.get(filePathString); if (Files.notExists(path)) { System.err.println("File path is incorrect!! Please double check the value!"); return; } List<DataRow> data = readFile(path); List<DataRow> sortedData = data.stream() .sorted(Comparator.comparing(DataRow::date)) .toList(); String msg = """ File found. Please write date for which you want to see the data. The date format must be like 2021-11-01 -> year-month-day. Please consider that date range is from %s until %s date. Date input: """; LocalDate startDate = sortedData.get(0).date; LocalDate endDate = sortedData.get(sortedData.size() - 1).date; System.out.format(msg, startDate.format(dtf), endDate.format(dtf)); String dateForSearching = in.nextLine(); LocalDate localDateUserInput = LocalDate.parse(dateForSearching, dtf); if(startDate.isAfter(localDateUserInput)) { System.err.print("User input date is before first date inside file!!"); return; } if(endDate.isBefore(localDateUserInput)) { System.err.print("User input date is after last date inside file!!"); return; } Optional<DataRow> result = sortedData.stream() .filter(d -> d.date.equals(localDateUserInput)) .findFirst(); String outputString = "Bitcoin price for this day high -> %s , low -> %s"; result.ifPresentOrElse( dataRow -> System.out.format(outputString, dataRow.high, dataRow.low), () -> System.err.print("No data was found in the file for this date!") ); } catch (IOException e) { throw new RuntimeException(e); } } public static List<DataRow> readFile(Path path) throws IOException { List<DataRow> dataRows; try (BufferedReader reader = Files.newBufferedReader(path)) { dataRows = reader.lines() .skip(1) .map(MainReadCSV::parseStringToDataRow).toList(); } return dataRows; } private static DataRow parseStringToDataRow(String line) { String[] parts = line.split(","); LocalDate date = LocalDate.parse(parts[0], dtf); BigDecimal high = new BigDecimal(parts[2]); BigDecimal highRounded = high.setScale(2, RoundingMode.HALF_EVEN); BigDecimal low = new BigDecimal(parts[3]); BigDecimal lowRounded = low.setScale(2, RoundingMode.HALF_EVEN); return new DataRow(date, highRounded, lowRounded); } }
Output:
Please enter the path to the file and please
don't leave empty spaces else they need to be escaped.
1. If you are using Windows then make
sure you path looks in format:
c:\folder\BTC-USD.csv
2. If you are using Linux/Unix then the format:
/home/username/BTC-USD.csv
fileInput:
/home/user/Downloads/BTC-USD.csv
File found. Please write date for which you want to see the data.
The date format must be like 2021-11-01 -> year-month-day.
Please consider that date range is from 2021-10-31 until 2022-10-31 date.
Date input:
2021-12-01
Bitcoin price for this day high -> 59041.68 , low -> 56553.08