【问题标题】:Command line argument passing to call method命令行参数传递给调用方法
【发布时间】:2019-08-01 09:19:48
【问题描述】:

如何将字符串的命令行参数传递给 java main 方法,该方法将调用另一个类中的特定方法?

我需要能够传递“java Statdriver mean”将调用 mean 方法或“java Statdriver std”将调用标准偏差方法,或者不传递任何参数将导致通过终端调用 mean 方法。

按我的方式做似乎行不通。我认为我的问题在于 if、else if、else 循环。

这是我的代码:

public class StatDriver
{

   public static void main(String[] args)
   {
      Scanner input = new Scanner(System.in);

      double total;
      double mean;
      double standardDeviation;
      double average;


      total = 0;

      args[0] = "mean";
      args[1] = "std";

      ArrayList<Double> data = new ArrayList<Double>();

      while(input.hasNextDouble())
      {
         data.add(input.nextDouble());
      }

      if(args.equals(args[0]))
      {
         mean = Stats.mean(data);
         System.out.println("Mean: " + mean);
      }

      else if(args.equals(args[1]))
      {
         standardDeviation = Stats.stdDev(data);
         System.out.println("StdDev: " + standardDeviation);
      }

      else
      {
         mean = Stats.mean(data);
         System.out.println("Mean: " + mean);
      }




     // mean = Stats.mean(data);
    //standardDeviation = Stats.stdDev(data);


    //System.out.println("Mean: " + mean);
    // System.out.println(" StdDev: " + standardDeviation);



   }  

}

【问题讨论】:

标签: java list if-statement arraylist while-loop


【解决方案1】:

使用 Java 反射特性时,解决方案简单易行。这是代码

    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Scanner;

    public class StatDriver {

        public static void main(String[] args)
        {
            Scanner input = new Scanner(System.in);
            ArrayList<Double> data = new ArrayList<Double>();

            while(input.hasNextDouble()) {
                data.add(input.nextDouble());
            }

            int length = args.length;

            if(length == 0) {
                double mean = Stats.mean(data);  // By default , mean method is called
        System.out.println(" Result (Mean) :"+mean);
    }
    else if(length > 0) {
        String methodName = args[0];

        try {
            Method method = Stats.class.getMethod(methodName, ArrayList.class);
            method.setAccessible(true);
            Object result = method.invoke(null , data);
            System.out.println("Result of the method :"+methodName+" is "+result);
                }
                catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class Stats{

        public static double mean(ArrayList aList) {
            double result = 0.0D;
            //Logic here
            return result;
        }

        public static double stdDev(ArrayList aList) {
            double result = 0.0D;
            //Logic here
            return result;
        }
    }

【讨论】:

    【解决方案2】:

    如何使用interface 并在其中包含一个与Stat 类的方法具有相同覆盖签名的方法:

    interface StatsOperation{
           double compute(List<Double> data);
    }
    

    Stat 类如下:

    class Stats{
            public static double mean(List<Double> data){
                System.out.println("mean invoked");
                //compute mean 
            }
            public static double stdDev(List<Double> data){
                System.out.println("stddev invoked");
               //compute std dev
            }
     }
    

    现在在主方法中,您可以使用Map 来保存Stats 类的方法引用(假设您使用的是Java-8):

    public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            Map<String, StatsOperation> lookup = new HashMap<>();
            lookup.put("mean", Stats::mean); //"mean" corresponds to Stats::mean implementation
            lookup.put("stddev", Stats::stdDev); //"stddev" corresponds to Stats::mean implementation
            ArrayList<Double> data = new ArrayList<Double>();
            while(input.hasNextDouble())
            {
                data.add(input.nextDouble());
                if(data.size() == 5) break; //breaking after 5 elements
            }
            StatsOperation operation = args.length > 0 && lookup.get(args[0]) != null ? lookup.get(args[0]) : lookup.get("mean"); //by default calling mean if nothing is sent in args array
            double result = operation.compute(data);
            System.out.println("Output " + result);
            // other business logic below
     }
    

    因此,根据您在args 数组中传递的值,我们将通过从Map 获取实现来调用该操作。这使用运行时多态性来决定在运行时调用哪个方法。

    【讨论】:

      【解决方案3】:

      命令行参数是在命令行“java classname”之后指定的单词。所以,如果你执行这个:

      java Statdriver mean
      

      ...您的main 方法将获得一个长度为1 的args 数组,其中包含"mean" 作为一个元素。

      如果你执行这个:

      java Statdriver std
      

      ...您的 main 方法将获得一个长度为 1 的 args 数组,其中包含 "std" 作为一个元素。

      在所有这些情况下,args 的长度都是 1。你应该只检查args[0]。没有args[1],尝试访问会抛出异常。

      正如 Andronicus 指出的那样,您正在尝试将值分配给 args,您不应该这样做。其实你根本不需要改args

      只需检查args[0] 是否等于每个有意义的字符串值:

        if (args[0].equals("mean"))
        {
           mean = Stats.mean(data);
           System.out.println("Mean: " + mean);
        }
      
        else if (args[0].equals("std"))
        {
           standardDeviation = Stats.stdDev(data);
           System.out.println("StdDev: " + standardDeviation);
        }
      
        else
        {
           mean = Stats.mean(data);
           System.out.println("Mean: " + mean);
        }
      

      考虑一下您真正想要检查的内容会有所帮助。好的代码读起来就像自然思维或说话:“如果第一个参数是“均值”,则计算均值,否则如果第一个参数是“标准差”,则计算标准差”等等。

      【讨论】:

        【解决方案4】:
        public class StatDriver
        {
        
           public static void main(String[] args)
           {
              Scanner input = new Scanner(System.in);
        
              double total;
              double mean;
              double standardDeviation;
              double average;
        
        
              total = 0;
        
              ArrayList<Double> data = new ArrayList<Double>();
        
              while(input.hasNextDouble())
              {
                 data.add(input.nextDouble());
              }
        
              if(args[0].equals("mean"))
              {
                 mean = Stats.mean(data);
                 System.out.println("Mean: " + mean);
              }
        
              else if(args[1].equals("std"))
              {
                 standardDeviation = Stats.stdDev(data);
                 System.out.println("StdDev: " + standardDeviation);
              }
        
              else
              {
                 mean = Stats.mean(data);
                 System.out.println("Mean: " + mean);
              }
        
           }  
        
        }
        

        【讨论】:

        • 如果您解释了您所做的更改以及更改的原因,这将是一个更好的答案。
        • args[0] = "mean"; args[] = "std' 。这是你的代码的错误。
        【解决方案5】:

        您正在覆盖 args 变量。应该是这样的:

        public class StatDriver
        {
        
           public static void main(String[] args)
           {
              Scanner input = new Scanner(System.in);
        
              double total;
              double mean;
              double standardDeviation;
              double average;
        
        
              total = 0;
        
              String[] possibleArgs = new String[2];
              possibleArgs[0] = "mean";
              possibleArgs[1] = "std";
        
              ArrayList<Double> data = new ArrayList<Double>();
        
              while(input.hasNextDouble())
              {
                 data.add(input.nextDouble());
              }
        
              if(possibleArgs[0].equals(args[0]))
              {
                 mean = Stats.mean(data);
                 System.out.println("Mean: " + mean);
              }
        
              else if(possibleArgs[1].equals(args[1]))
              {
                 standardDeviation = Stats.stdDev(data);
                 System.out.println("StdDev: " + standardDeviation);
              }
        
              else
              {
                 mean = Stats.mean(data);
                 System.out.println("Mean: " + mean);
              }
        
           }  
        
        }
        

        【讨论】:

          猜你喜欢
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-09
          • 2017-10-22
          • 2019-10-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多