Here, we will create a Custom CommandLineParser class to parse the arguments passed via command line in Java.
Let’s first see the sample entry point for 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 array of strings as arguments in main method of Java?
It’s for the command line arguments. When you run your Java program from command line:

java MyProgram Oshan 

It takes “Oshan” as 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 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 these each string as 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 command line. This way we don’t have to hard code the arguments values 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 array of string.

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+" ");
    }

Output of the above program will be:

This is only a test
Oshan
Oshan
Oshan

You can also use method getArgumentNames to see the passed arguments names.
I recently encountered a problem which made me write this custom CommandLineParser. Obviously, you can modify this to fit your requirements or go with 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.