Java console application
last modified July 13, 2020
Java console application tutorial shows how to create a Java console application. The application computes some statistics.
2.3, 3.5, 5, 6.7, 3.2, 1.2, 6.7, 7.8 4.5, 2.1, 6.6, 8.7, 3.2, 1.0, 1.2, 3
Somewhere on the disk we have this file. The file name will be a console parameter to our program.
$ tree . ├── nbactions.xml ├── pom.xml └── src ├── main │ └── java │ └── com │ └── zetcode │ ├── JavaStatsEx.java │ └── MyStatsApp.java └── test └── java
This is the project structure.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>JavaConsoleApp</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>4.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-math3</artifactId> <version>3.6.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.5.0</version> <configuration> <mainClass>com.zetcode.JavaStatsEx</mainClass> <cleanupDaemonThreads>false</cleanupDaemonThreads> <arguments> <argument>-f</argument> <argument>/home/janbodnar/tmp/data.csv</argument> </arguments> </configuration> </plugin> </plugins> </build> </project>
In the pom.xml
file, we define the dependencies of
the application. The commons-cli
artifact is for parsing
command line arguments, opencsv
for reading CSV data,
commons-math
for statistical calculations,
and commons-lang3
for transforming list into an array.
The exec-maven-plugin
executes Java programs from Maven.
In the arguments
tag, we give the application the option
and the filename.
package com.zetcode; /** * Starter class for MyStats application. * * @author janbodnar */ public class JavaStatsEx { /** * Application entry point. * * @param args application command line arguments */ public static void main(String[] args) { MyStatsApp msp = new MyStatsApp(); msp.run(args); } }
JavaStatsEx
is the application entry point. It creates
the instance of MyStatsApp
and passes it the application
arguments.
package com.zetcode; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; import java.io.IOException; import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.math3.stat.StatUtils; /** * MyStatsApp is a simple console application which computes * basic statistics of a series of data values. The application takes * a file of data as its single argument. * * @author janbodnar */ public class MyStatsApp { /** * Runs the application * * @param args an array of String arguments to be parsed */ public void run(String[] args) { CommandLine line = parseArguments(args); if (line.hasOption("filename")) { System.out.println(line.getOptionValue("filename")); String fileName = line.getOptionValue("filename"); double[] data = readData(fileName); calculateAndPrintStats(data); } else { printAppHelp(); } } /** * Parses application arguments * * @param args * @return <code>CommandLine</code> which represents a list of application * arguments. */ private CommandLine parseArguments(String[] args) { Options options = getOptions(); CommandLine line = null; CommandLineParser parser = new DefaultParser(); try { line = parser.parse(options, args); } catch (ParseException ex) { System.err.println(ex); printAppHelp(); System.exit(1); } return line; } /** * Reads application data from a file * * @param fileName * @return array of double values */ private double[] readData(String fileName) { List<Double> data = new ArrayList(); double[] mydata = null; try (Reader reader = Files.newBufferedReader(Paths.get(fileName)); CSVReader csvReader = new CSVReaderBuilder(reader).build()) { String[] nextLine; while ((nextLine = csvReader.readNext()) != null) { for (String e : nextLine) { data.add(Double.parseDouble(e)); } } mydata = ArrayUtils.toPrimitive(data.toArray(new Double[data.size()])); } catch (IOException ex) { System.err.println(ex); System.exit(1); } return mydata; } /** * Generates application command line options * * @return application <code>Options</code> */ private Options getOptions() { Options options = new Options(); options.addOption("f", "filename", true, "file name to load data from"); return options; } /** * Prints application help */ private void printAppHelp() { Options options = getOptions(); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("JavaStatsEx", options, true); } /** * Calculates and prints data statistics * * @param data input data */ private void calculateAndPrintStats(double[] data) { System.out.format("Geometric mean: %f%n", StatUtils.geometricMean(data)); System.out.format("Arithmetic mean: %f%n", StatUtils.mean(data)); System.out.format("Max: %f%n", StatUtils.max(data)); System.out.format("Min: %f%n", StatUtils.min(data)); System.out.format("Sum: %f%n", StatUtils.sum(data)); System.out.format("Variance: %f%n", StatUtils.variance(data)); } }
This is MyStatsApp
.
CommandLine line = parseArguments(args);
The parseArguments
method parses the command line arguments.
It returns CommandLine
, which represents a list of
arguments parsed against a Options
descriptor.
if (line.hasOption("filename")) { System.out.println(line.getOptionValue("filename")); String fileName = line.getOptionValue("filename"); double[] data = readData(fileName); calculateAndPrintStats(data); } else { printAppHelp(); }
The application has a mandatory filename option, which points to the file to be read and compute statistics from. If it is not present, we provide the application help message.
Options options = getOptions();
The getOptions
method returns the options of the application.
CommandLineParser parser = new DefaultParser(); try { line = parser.parse(options, args); } catch (ParseException ex) { System.err.println(ex); printAppHelp(); System.exit(1); } return line;
CommandLineParser
parses the command line arguments.
The application exits if there is a ParseException
.
The parser returns parsed arguments in CommandLine
object.
try (Reader reader = Files.newBufferedReader(Paths.get(fileName)); CSVReader csvReader = new CSVReaderBuilder(reader).build()) {
CSVReader
is used to read CSV data.
String[] nextLine; while ((nextLine = csvReader.readNext()) != null) { for (String e : nextLine) { data.add(Double.parseDouble(e)); } }
In this while loop, we read the CSV file line by line and parse the data
into a list of Double
values.
mydata = ArrayUtils.toPrimitive(data.toArray(new Double[data.size()]));
We need primitive data types to calculate the statistics; therefore,
we transform the list into an array of primitive double values.
ArrayUtils
comes from the Apache Commons Lang library.
private Options getOptions() { Options options = new Options(); options.addOption("f", "filename", true, "file name to load data from"); return options; }
The getOptions
provides the application options.
private void printAppHelp() { Options options = getOptions(); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("JavaStatsEx", options, true); }
The printAppHelp
prints the help of the application.
It uses HelpFormatter
to do the job.
private void calculateAndPrintStats(double[] data) { System.out.format("Geometric mean: %f%n", StatUtils.geometricMean(data)); System.out.format("Arithmetic mean: %f%n", StatUtils.mean(data)); System.out.format("Max: %f%n", StatUtils.max(data)); System.out.format("Min: %f%n", StatUtils.min(data)); System.out.format("Sum: %f%n", StatUtils.sum(data)); System.out.format("Variance: %f%n", StatUtils.variance(data)); }
With StatUtils
, we compute some statistics.
The StatUtils
takes a Java array as a parameter.
$ mvn -q exec:java /home/janbodnar/tmp/data.csv Geometric mean: 3.412562 Arithmetic mean: 4.168750 Max: 8.700000 Min: 1.000000 Sum: 66.700000 Variance: 6.158292
In this tutorial, we have created a simple Java console application, which computes basic statistics from a CSV file.