【问题标题】:How can I give command line arguments in any order?如何以任何顺序给出命令行参数?
【发布时间】:2014-08-05 02:20:37
【问题描述】:

我有两个枚举,一个用于应用程序,一个用于环境。我希望能够以任何顺序给出这些参数,所以我可以给出 -app app1 app1 -env env1 env2 或 -env env1 env2 -app app1 app2。现在我只能做第一个。我还希望能够只说 -app app1 app2 它运行我在所有环境中列出的所有应用程序,并且对于环境也是如此,但我更关心能够以任一顺序提供它们。

 for(int i = 0; i<args.length; i++)
            {
                if(args[i].equals("-app"))
                {
                    indexOfApp = i;
                }else if(args[i].equals("-env"))
                {
                    indexOfEnv = i;
                }
            }

            int countOfApp = -1;
            int countOfEnv = -1;

            if(indexOfApp != -1 && indexOfEnv != -1)
            {
                countOfApp = indexOfEnv - 1;
                countOfEnv = args.length - (indexOfEnv + 1);
            }


            System.out.println(countOfApp);

            System.out.println(countOfEnv);

            for(int appIndex = indexOfApp + 1; appIndex < countOfApp + 1; appIndex++){
                appList.add(args[appIndex]);

            }
                for(String item : appList )
                {
                    Application app = Application.valueOf(Application.class, item);
                    appList2.add(app);
                }
            for(int envIndex = indexOfEnv + 1; envIndex < args.length; envIndex++){
                envList.add(args[envIndex]);

            }
            for(String item : envList )
            {
             Environment env = Environment.valueOf(Environment.class, item);
                envList2.add(env);
            }

            }    System.out.println(appList); System.out.println(envList);
        Application.chooseAppTest(appList2, envList2);

【问题讨论】:

  • 为什么不使用库? JOpt、Commons CLI、JCommander、Args4j、...其中大部分将提供您所寻找的开箱即用的东西。
  • 我发现了一个很长的命令行参数解析器列表:stackoverflow.com/a/7829772/10077
  • @RobbyCornelissen 我的经理(我只是一名实习生)告诉我,通常使用库会更好,但现在使用它会使运行它变得复杂。跨度>
  • 我知道这听起来很愚蠢,但我应该在这里重新发明轮子。

标签: java command-line-arguments


【解决方案1】:

它可以更简单:

boolean isApp = false;
boolean isEnv = false;

for (int i = 0; i<args.length; i++) {
    if (args[i].equals ("-app")) {
        isApp = true;
        isEnv = false;
    } else if (args[i].equals ("-env")) {
        isEnv = true;
        isApp = false;
    } else if (isEnv) {
        envList.add(args[i]);
    } else if (isApp) {
        appList.add(args[i]);
    }
}

【讨论】:

    【解决方案2】:

    此解决方案是可扩展的,因为它没有经过硬编码:

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Main {
        // this method does all the work
        static private String[] getArgs(String argArray[],String indicator){            
            String arguments="";
            for (String s: argArray){
                arguments = arguments + s +" ";
            }
            arguments = arguments.trim();
            Pattern p = Pattern.compile(indicator+" ([^\\-]*)");    
            Matcher m = p.matcher(arguments);
            String[] newArgs={};
            try {
                m.find();
                newArgs = m.group(1).split(" ");
            } catch (IllegalStateException e){              
            }               
            return newArgs;         
        }
    
        public static void main (String args[]){            
            System.out.println("ENVS");
            String[] e=getArgs(args,"-env");
            for (String s: e){
                System.out.println(s);
            }           
            System.out.println("APPS");
            e=getArgs(args,"-app");
            for (String s: e){
                System.out.println(s);
            }               
        }
    }
    

    示例输出:

    java Main -env env1 env2 env3 -app app1 app2
    ENVS
    env1
    env2
    APPS
    app1
    app2
    
    
    java Main -app app1 app2 app3 app4 -env env1 env2
    ENVS
    env1
    env2
    APPS
    app1
    app2
    app3
    app4
    
    
    java Main -app app1 app2
    ENVS
    APPS
    app1
    app2
    

    【讨论】:

      【解决方案3】:

      上周有人给了你这个问题的另一个版本的答案,你已经问了三四次了,这正是你想要的。我现在找不到(可能已被删除),但本质上是这段代码:

      public static void main(String[] args) {
          List<String> apps = new ArrayList<>();
          List<String> envs = new ArrayList<>();
          List<String> destination = null;
      
          for (String arg : args) {
              if ("-app".equals(arg)) {
                  destination = apps;
              } else if ("-env".equals(arg)) {
                  destination = envs;
              } else if (destination == null) {
                  System.out.printf("Invalid argument: %s%n", arg);
              } else {
                  destination.add(arg);
              }
          }
      }
      

      我不明白您为什么忽略此解决方案,因为它完全符合您的要求。 (当时你问的是把字符串拆分成数组,出于某种奇怪的原因。)

      你可以这样做:

      public static void main(String[] args) {
          List<Application> apps = new ArrayList<>();
          List<Environment> envs = new ArrayList<>();
          boolean appFlag = false;
          boolean envFlag = false;
      
          for (String arg : args) {
              if ("-app".equals(arg)) {
                  appFlag = true;
                  envFlag = false;
              } else if ("-env".equals(arg)) {
                  envFlag = true;
                  appFlag = false;
              } else if (appFlag) {
                  apps.add(Application.valueOf(arg));
              } else if (envFlag) {
                  envs.add(Environment.valueOf(arg));
              } else {
                  System.out.printf("Invalid argument: %s%n", arg);
              }
          }
          Application.chooseAppTest(apps, envs);
      }
      

      【讨论】:

      • 我没有忽视他们。显然,它们不像我需要它们那样工作。我保证我尝试了人们给我的东西,我试着调整他们做我需要的东西。我问了关于拆分字符串的问题,因为这就是我最初被告知要做这个任务的方式。如果您一开始就这样帮助我,那将不是问题。谢谢。
      【解决方案4】:

      自己实现这一点非常容易。使用前导 - 作为指标。
      试试这个代码。我想这就是你想要的。这个解决方案也很通用,
      即使您稍后添加其他参数类型(不仅仅是-app-env),它也会起作用。

      import java.util.HashMap;
      import java.util.ArrayList;
      
      
      public class Test006 {
      
          public static void main(String[] args) {
              System.out.println(args.length);
      
              HashMap<String, ArrayList<String>> mp = 
              new HashMap<String, ArrayList<String>>();
      
              String key = "";
              for (int i=0; i<args.length; i++){
                  if (args[i].startsWith("-")){
                      mp.put(args[i], new ArrayList<String>());
                      key = args[i];
                  }else{
                      mp.get(key).add(args[i]);
                  }
              }
      
              for (String k : mp.keySet()){
                  System.out.println("---->" + k);
                  for (String s : mp.get(k)){
                      System.out.println("///" + s);
                  }
              }
          }
      
      }
      

      输出:

      C:\Programs\eclipse\workspace\_TEST>java -cp ./bin Test006 -app a1 a2 -env e1 e2
      6
      ---->-env
      ///e1
      ///e2
      ---->-app
      ///a1
      ///a2
      
      C:\Programs\eclipse\workspace\_TEST>java -cp ./bin Test006 -env e1 e2 -app a1 a2
      6
      ---->-env
      ///e1
      ///e2
      ---->-app
      ///a1
      ///a2
      
      C:\Programs\eclipse\workspace\_TEST>
      

      【讨论】:

        【解决方案5】:

        这是我会做的:

        1.创建一个枚举 - 您想要添加的任何其他参数都应该添加到此列表中

        enum Args {
        
            ENV("-env"),
        
            APP("-app"),
        
            NONE("");
        
            String argCode;
        
            /**
             * @return the argCode
             */
            public String getArgCode() {
                return argCode;
            }
        
            Args(String argCode){
                this.argCode = argCode;
            }
        
            /**
             * @param str
             * @return
             */
            public static Args getArgs(String str){
                for (Args arg : Args.values()){
                    if (arg.getArgCode().equalsIgnoreCase(str)){
                        return arg;
                    }
                }
        
                return NONE;
            }
        
        }
        

        2。现在有以下 - 这些行运行以准备一个映射,其中参数名称作为键,它的值作为值列表

        public static void main(String[] args) {
        
            HashMap <String, ArrayList<String>> argMap = new HashMap<String, ArrayList<String>>();
        
            String argCode = null;
        
            for (String arg: args){
                Args a = Args.getArgs(arg);
        
                if (!a.equals(Args.NONE)){
                    argCode = a.getArgCode();
                    continue;
                }
        
                ArrayList<String> argList = argMap.get(argCode);
        
                if (argList == null){
                    argList = new ArrayList<String>();
        
                    argMap.put(argCode, argList);
                }
        
                argList.add(arg);
            }
        
            System.out.println(argMap.toString());
        
        }
        

        3。下面是输出:使用地图获取值列表

        {-env=[env1, env2], -app=[app1, app1]}

        万一你有另一个参数添加到列表中说“-sample”只需添加到枚举列表中,如下所示:

            ENV("-env"),
        
            APP("-app"),
        
            Sample("-sample"),
        
            NONE("");
        

        地图也会有这个键值对。

        以下操作也可以:

        -env env1 -app app1 -env env2 -app app2

        如果您不希望上述方法起作用,请检查 main 方法中的键是否重复。希望答案对您有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-23
          • 2021-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-12
          • 2011-05-20
          相关资源
          最近更新 更多