2016-08-15 73 views
0

過去,我需要檢查,如果Java命令行參數傳遞順序是:檢查命令行參數以有效的順序

-shape (optional - default polygon) 
-color (optional - default green) 
-repeat (optional - default 5) 
-name (required) 

,沒有不確定參數的使用。

如果可選參數未通過,則使用默認值。

有效期:

java Game -shape triangle -color black -repeat 10 -name Tom 
java Game -shape triangle -repeat 7 -name Jerry 
java Game -repeat 11 -name Boby 
java Game -name Pipy 

無效:

java Game -shape triangle -x sth -name Tom (invalid argument: -x) 
java Game -shape triangle (-name is required) 
java Game -color white -shape triangle (wrong order: -shape must be before -color) 

爲優雅的解決方案什麼建議嗎?

+0

您可以怎樣利用正則表達式 – Blobonat

+0

@Blobonat?在'String []'上? – fabian

+0

@fabian他可以將args-array連接到一個字符串。 – Blobonat

回答

1

你可以存儲在一個列表中的所有選項,並簡單地嘗試逐一對命令行參數,直到找到一個匹配:

public static class OptionParser<T> implements ParameterParser { 

    private final String option; 

    public OptionParser(String option, Function<String, ? extends T> parser) { 
     if (parser == null) { 
      throw new IllegalArgumentException(); 
     } 
     this.option = "-" + option; 
     this.parser = parser; 
    } 

    public OptionParser(String option, Function<String, ? extends T> parser, T defaultValue) { 
     this(option, parser); 
     this.value = defaultValue; 
    } 

    private final Function<String, ? extends T> parser; 

    private T value; 

    @Override 
    public int parse(String[] args, int index) { 
     if (args.length < index + 2 || !option.equals(args[index])) { 
      return index; 
     } else { 
      value = parser.apply(args[index + 1]); 
      return index + 2; 
     } 
    } 

    public T getValue() { 
     return value; 
    } 

} 

public static interface ParameterParser { 


    /** 
    * Tries parsing the parameter and returns the new index after the 
    * operation. 
    * 
    * @param args the parameter list 
    * @param index the index of the first String to use. 
    * @return the index of the next String after parsing the parameter or the index, 
    * if the parameter wasn't parsable with this ParameterParser. 
    */ 
    public int parse(String[] args, int index); 
} 

public static void main(String[] args) { 
    OptionParser<String> shape = new OptionParser<>("shape", Function.identity(), "polygon"); 
    OptionParser<String> color = new OptionParser<>("color", Function.identity(), "green"); 
    OptionParser<Integer> repeat = new OptionParser<>("repeat", Integer::valueOf, 5); 
    OptionParser<String> name = new OptionParser("name", Function.identity()); 

    List<ParameterParser> parameters = Arrays.asList(
      shape, 
      color, 
      repeat, 
      name 
    ); 

    Iterator<ParameterParser> iterator = parameters.iterator(); 

    for (int i = 0; i < args.length;) { 
     if (!iterator.hasNext()) { 
      throw new IllegalArgumentException("could not parse option at index " + i + ": " + args[i]); 
     } 
     i = iterator.next().parse(args, i); 
    } 

    if (name.getValue() == null) { 
     throw new IllegalArgumentException("-name is required"); 
    } 

    System.out.println("shape="+shape.getValue()); 
    System.out.println("color="+color.getValue()); 
    System.out.println("repeat="+repeat.getValue()); 
    System.out.println("name="+name.getValue()); 
+0

非常好。謝謝! –