Java命令行解析参数类ArgumentsParser 郝伟 2021/05/06 [TOC]

1. 1 简介

在Python中有argment.Parser用于处理输入参数,为了在Java实现类似的功能。本文编写了一种用于处理main函数中的输入参考 String[] args 的类 ArgumentsParser

命令通用由多个由空格隔开,带有横杠(-)、键值(key)和值域(value)组成,每个标签格式如下所示: -key str1 str2,比如 -path ./src ./data 多个标签间也使用空格隔开,以下是一条Java的编码示例:javac -encoding utf8 -t -d ./bin -cp /Users/hao/servlet-api.jar ./src/*.java` 其中就包括了三组标签:

  1. -encoding utf8
  2. -t
  3. -d ./bin
  4. -cp /Users/hao/servlet-api.jar ./src/*.java

其中标签2的参数个数为0,标签1,3为1,标签4的参数个数为4。

2. 2 类功能介绍

2.1. 2.1 初始化

本类使用 String[] args 作为初始化化函数: ArgumentsParser ap = new ArgumentsParser(args); 其中 args 就是 main 函数传递进来的所有参数。

2.2. 2.2 主要函数

类中的主要非静态函数的作用如下:

函数名称 作用
boolean hasKey(String key) 判断key是否存在。
Set getKeys() 返回所有的Key。
String getString(String key) 返回指定key的字符串值,如果有多个值,只返回第1个值。
String getString(String key, String defaultValue) 返回指定key的字符串值(只返回第1个值),如果不存在则返回缺省值 defaultValue。
String[] getStrings(String key) 返回指定key的所有值列表。
int getInt(String key) 返回指定key的对应的整型,如果转换失败会抛出转换失败异常。

3. 3 源代码

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class ArgumentsParser {

    public static void main(String args[]) {
        // for test
        args = "-encoding utf8 -t -print 5 -d ./bin -cp /Users/hao/servlet-api.jar ./src/*.java".split(" ");

        ArgumentsParser ap = new ArgumentsParser(args);
        System.out.println("---------- Basic Test ---------");
        String name = ap.getString("encoding");
        int prints = Integer.parseInt(ap.getString("print"));
        for (String path : ap.getStrings("paths"))
            System.out.println(path);

        String out_path = ap.hasKey("out") ? ap.getString("out") : "c:\\output";
        System.out.println("Output Path: " + out_path);

        System.out.println("---------- Get Argument Strings ---------");
        for (String name1 : ap.getKeys())
            System.out.println(name1 + ": " + ap.getStrings(name1).length);

        System.out.println("---------- Key Existance Check ---------");
        System.out.println("hasKey(\"encoding\"): " + ap.hasKey("test"));
        System.out.println("hasKey(\"name\"): " + ap.hasKey("name"));
        System.out.println("hasKey(\"cp\"): " + ap.hasKey("path"));
        System.out.println("hasKey(\"d\"): " + ap.hasKey("paths"));

        System.out.println("---------- use arguments ---------");
        for (int i = 0; i < prints; i++) {
            System.out.print(name + ", ");
        }
    }

    HashMap<String, List<String>> map = new HashMap<>();

    ArgumentsParser(String arguments[]) {
        List<String> args = Arrays.asList(arguments);
        for (String arg : args) {
            // case 1: non-hyphen started arguments.
            if (!arg.startsWith("-"))
                continue;

            // case 2: tags with 0 argument values.
            String key = arg.substring(1);
            int arg_index = args.indexOf(arg);
            if (arg_index == args.size() - 1 || args.get(arg_index + 1).startsWith("-")) {
                map.put(key, new ArrayList<String>());
                continue;
            }

            // case 3: key with 1 or more argument values
            List<String> argstrs = new ArrayList<>();
            int i = 1;
            while (arg_index + i != args.size() && !args.get(arg_index + i).startsWith("-")) {
                argstrs.add(args.get(arg_index + i));
                i++;
            }
            map.put(arg.replace("-", ""), argstrs);
        }
    }

    public boolean hasKey(String keyName) {
        if (map.containsKey(keyName))
            return true;
        return false;
    }

    // Return argument names
    public Set<String> getKeys() {
        return map.keySet();
    }

    public String getString(String keyName) {
        return getString(keyName, null);
    }

    public String getString(String keyName, String defaultValue) {
        return this.hasKey(keyName) ? map.get(keyName).get(0) : defaultValue;
    }

    public String[] getStrings(String argumentName) {
        if (map.containsKey(argumentName))
            return map.get(argumentName).toArray(new String[0]);
        else
            return new String[0];
    }

    public int getInt(String keyName, int defaultValue) {
        int retValue = 0;
        try {
            if (hasKey(keyName))
                retValue = Integer.parseInt(map.get(keyName).get(0));
        } catch (Exception ex) {
            retValue = defaultValue;
        }
        return retValue;
    }
}

4. 4 输出结果

---------- Basic Test ---------
Output Path: c:\output
---------- Get Argument Strings ---------
print: 1
t: 0
d: 1
encoding: 1
cp: 2
---------- Key Existance Check ---------
hasKey("encoding"): false
hasKey("name"): false
hasKey("cp"): false
hasKey("d"): false
---------- use arguments ---------
utf8, utf8, utf8, utf8, utf8,

results matching ""

    No results matching ""