Apache Commons CLI - 如何对帮助选项进行排序?

13

我正在使用Apache Commons CLI库。默认情况下,该库会按照key的字母顺序在命令行中排序帮助选项。所以,显示的内容是:

-csv
-ip
-msisdn
-xml

但我想按以下顺序排序:

-csv
-xml
-ip
-msisdn
我知道有一个OptionFormatter类可以使用,并且可以传递给HelpFormatter,但我找不到任何关于如何将其用于上述目的的示例(http://www.marko.homeunix.org/programming/java/commons-cli/api/org/apache/commons/cli/HelpFormatter.OptionComparator.html)。
只是想知道是否有人做过类似的事情?
谢谢。

哇。你会认为那么简单的东西应该能用。 - MK.
6个回答

27

从v1.3开始,您可以调用setOptionComparator(null),这样格式化程序将跳过排序,并按照它们添加的顺序打印参数。

HelpFormatter formatter = new HelpFormatter();
formatter.setOptionComparator(null);

链接到实际问题。


10
自 Apache Commons CLI 1.2 版本开始,您可以直接在 HelpFormatter 类上设置比较器:
setOptionComparator [link] public void setOptionComparator(Comparator comparator)
设置用于在帮助文本中输出选项时对选项进行排序的比较器。传入 null 参数将设置排序方式为默认模式。
您应该提供自己的 Comparator<Option> 实现,以按您所需的顺序对选项进行排序。

1
默认是按字母顺序排序的,因此传递 null 是没有帮助的。 - Scott McIntyre
1
@smackfu 谢谢 - 已移除。 - Duncan Jones
1
从Apache Commons CLI 1.3开始,传递null比较器到setOptionComparator(Comparator comparator)的结果已经改变。来自文档:传递null比较器将保持选项声明的顺序。 - dguay

9

实现这种比较器的最佳KISS方法是:

class OptionComparator<T extends Option> implements Comparator<T> {

    private static final String OPTS_ORDER = "abcdef"; // short option names

    public int compare(T o1, T o2) {
        return OPTS_ORDER.indexOf(o1.getOpt()) - OPTS_ORDER.indexOf(o2.getOpt());
    }
}

 


1
我宁愿使用 List,然后使用它的 indexOf("optName") 方法。或者更好的是,我会将添加到 Options 类中的相同 Option 实例添加到 List<Option> 中,然后在 Comparator 中使用列表的 indexOf(option) 方法。 - Miguel

3

目前不支持。

但是它是一个开源项目,所以你知道该怎么做...

来自源代码:

    private static class OptionComparator
    implements Comparator {

    /**
     * <p>Compares its two arguments for order. Returns a negative 
     * integer, zero, or a positive integer as the first argument 
     * is less than, equal to, or greater than the second.</p>
     *
     * @param o1 The first Option to be compared.
     * @param o2 The second Option to be compared.
     *
     * @return a negative integer, zero, or a positive integer as 
     * the first argument is less than, equal to, or greater than the 
     * second.
     */
    public int compare(Object o1, Object o2)
    {
        Option opt1 = (Option)o1;
        Option opt2 = (Option)o2;

        return opt1.getKey().compareToIgnoreCase(opt2.getKey());
    }
}

您可以覆盖默认比较器并定义所需的顺序。


1
如果您知道选项的确切顺序,可以将Order类扩展到包括您的排序号,并使用Options.add(Option opt)方法向Options实例提供OrderedOption实例。
然后,创建一个比较器并比较您的OrderedOptions中的顺序号...我建议不要在一个Options实例中混合两种类型的Option实例,因为它可能会使排序和在比较器中测试有效的OrderedOption实例变得复杂。

0
您可以使用以下代码对帮助值进行排序:
    HelpFormatter formatter = new HelpFormatter();
    // print the help options in the save order you added 
    formatter.setOptionComparator(new Comparator<Option>() {
        @Override
        public int compare(Option o1, Option o2) {
            List<Option> options = new ArrayList<Option>(getOptions().getOptions());
            Integer indexOfO1 = options.indexOf(o1);
            Integer indexOfO2 = options.indexOf(o2);
            return indexOfO1.compareTo(indexOfO2);
        }
    });
    formatter.printHelp("Commandline syntax", OPTIONS);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接