Here, we will create a Custom CommandLineParser class to parse the arguments passed via the command line in Java.
Let's first see the sample entry point for the Java program.
public class MyProgram{
public static void main(String args[])
{
System.out.println("This is my program.");
}
}
Ever wondered why do we need to pass an array of strings as arguments in main method of Java?
It's for the command line arguments. When you run your Java program from the command line:
java MyProgram Oshan
It takes "Oshan" as an argument. So, if you want your program to access this String
, you can access it using the array of String passed in the main method.
// inside main method
//Prints "My name is Oshan"
System.out.println("My name is ", args[0]);
You can pass the initial configuration you want your Java program to follow via command-line arguments. For example:
## if you want to send file path
java MyProgram -filePath file1.txt
## if you want to send multiple file paths
java MyProgram -filePath file1.txt file2.txt
## or, if you just want to send flags
java MyProgram -noprint
By default, Java takes each string as an argument and cannot differentiate between argument names, values, or flags. So, today, we'll write a simple program that will parse the arguments passed through the command line. This way we don't have to hard code the values of the arguments as args[1]
or args[2]
in our program. Instead, we will be able to see the argument list and choose values using argument names rather than an array of strings.
Here is the code:
import java.util.HashMap;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class CommandLineParser {
List <String> args = new ArrayList<>();
HashMap<String, List<String>> map = new HashMap<>();
Set<String> flags = new HashSet<>();
CommandLineParser(String arguments[])
{
this.args = Arrays.asList(arguments);
map();
}
// Return argument names
public Set<String> getArgumentNames()
{
Set<String> argumentNames = new HashSet<>();
argumentNames.addAll(flags);
argumentNames.addAll(map.keySet());
return argumentNames;
}
// Check if flag is given
public boolean getFlag(String flagName)
{
if(flags.contains(flagName))
return true;
return false;
}
// Return argument value for particular argument name
public String[] getArgumentValue(String argumentName)
{
if(map.containsKey(argumentName))
return map.get(argumentName).toArray(new String[0]);
else
return null;
}
// Map the flags and argument names with the values
public void map()
{
for(String arg: args)
{
if(arg.startsWith("-"))
{
if (args.indexOf(arg) == (args.size() - 1))
{
flags.add(arg.replace("-", ""));
}
else if (args.get(args.indexOf(arg)+1).startsWith("-"))
{
flags.add(arg.replace("-", ""));
}
else
{
//List of values (can be multiple)
List<String> argumentValues = new ArrayList<>();
int i = 1;
while(args.indexOf(arg)+i != args.size() && !args.get(args.indexOf(arg)+i).startsWith("-"))
{
argumentValues.add(args.get(args.indexOf(arg)+i));
i++;
}
map.put(arg.replace("-", ""), argumentValues);
}
}
}
}
}
Now, you can add the above class to any program you want and easily parse the values.
Let's try with a simple program:
public class MyProgram
{
public static void main (String args[])
{
CommandLineParser clp = new CommandLineParser(args);
}
}
Make sure you include the CommandLineParser
class in the classpath when you compile your program.
javac -classpath /pathToTheCommandLineParserClass MyProgram.java
java MyProgram.java -name Oshan -prints 3 -test
Now, in our program you can easily get these values and use it.
// inside main method
String name = clp.getArgumentValue("name");
int prints = Integer.parseInt(clp.getArgumentValue("prints"));
boolean isTest = clp.getFlag("test");
if(isTest)
System.out.println("This is only a test");
for(int i = 0; i < prints; i++)
{
System.out.print(name+" ");
}
The output of the above program will be:
This is only a test
Oshan
Oshan
Oshan
You can also use the method getArgumentNames
to see the passed argument names.
I recently encountered a problem that made me write this custom CommandLineParser
. Obviously, you can modify this to fit your requirements or go with the traditional approach. But, making such class removes the ambiguity when multiple arguments are passed via command line.
I hope you find this useful.
Thanks for reading.
Top comments (0)