简体   繁体   English

如何在java 8中将String [] args与“=”分开

[英]How transform String[] args with “=” split in java 8

I need to transform 我需要改造

String[] args = {"--path=C:/log", "--time=hourly"};

into

String[] args = {"--path", "C:/log", "--time", "hourly"};

How can I do this in Java 8, in an elegant way? 我怎样才能以优雅的方式在Java 8中做到这一点?

List<String> newArgs = Lists.newArrayList();

for (String s : args) {
    String[] split = s.split("=");
    newArgs.add(split[0]);
    newArgs.add(split[1]);
}

String[] strarray = new String[newArgs.size()];
return newArgs.toArray(strarray);
String[] result = Stream.of(args)
        .flatMap(a -> Stream.of(a.split("=")))
        .toArray(String[]::new);

The other answers are all fine technically, but the real answer is: don't. 其他答案在技术上都很好,但真正的答案是:不要。

Do not re-invent the wheel. 不要重新发明轮子。 Parsing command line options is actually hard . 解析命令行选项实际上很难 Whatever you come up with works for the first step, but assuming that we are talking about something that is intended to last, and good enough to attract users - then sooner or later, you spent more and more time on dealing with the options. 无论你为第一步做出什么工作,但假设我们正在谈论的是一些旨在持久的东西,并且足以吸引用户 - 那么迟早,你花了越来越多的时间来处理选项。

Thus: instead of doing any of this yourself (which is of course a bit of fun) accept that parsing command line options is a solved problem. 因此:不要自己做任何事情(这当然有点乐趣)接受解析命令行选项是一个已解决的问题。 Simply get one of the existing solutions, see here for starters. 只需获得一个现有的解决方案,请参阅此处的首发。

Explanation 说明

As you want to use Java 8 code you may use the Stream API ( documentation ). 如果您想使用Java 8代码,可以使用Stream API文档 )。

Therefore you should first transform your args array into a Stream<String> using the utility method Arrays#stream ( documentation ). 因此,您应该首先使用实用程序方法Arrays#streamdocumentation )将args数组转换为Stream<String> Then you split the arguments by = using String#split ( documentation ) and afterwards collect them again into an array using Stream#toArray ( documentation ). 然后使用String#splitdocumentation )将参数拆分为= ,然后使用Stream#toArray文档 )将它们再次收集到一个array

In order to treat each split value as regular value (and not as nested data) you may want to flatten the Stream . 为了将每个拆分值视为常规值(而不是嵌套数据),您可能希望展平 Stream So instead of Stream<String[]> you want to have a flattened structure like Stream<String> . 因此,您希望拥有像Stream<String>这样的扁平化结构,而不是Stream<String[]> Stream<String> You do so by using the Stream#flatMap method ( documentation ). 您可以使用Stream#flatMap方法( 文档 )。


Code

Here is variant using the explained approach: 以下是使用解释方法的变体:

String[] data = Arrays.stream(args)  // String
    .map(arg -> arg.split("="))      // String[]
    .flatMap(Arrays::stream)         // String
    .toArray(String[]::new);

You can also memorize the pattern beforehand and then use Pattern#splitAsStream ( documentation ): 您也可以预先记住模式,然后使用Pattern#splitAsStream文档 ):

Pattern patt = Pattern.compile("=");
List<String> data = Arrays.stream(args)  // String
    .map(patt::splitAsStream)            // String[]
    .flatMap(Arrays::stream)             // String
    .toArray(String[]::new);

This will produce a List, but you can transform it. 这将生成一个List,但您可以对其进行转换。

final List<String> parts = Arrays.stream(args)
    .flatMap(argument -> Arrays.stream(argument.split("=")))
    .collect(Collectors.toList());

You might consider argument.split("=", 2) . 你可以考虑argument.split("=", 2)

    String[] args = {"--path=C:/log", "--time=hourly"};
    args = String.join("=", args).split("=");
    System.out.println(Arrays.toString(args));

I was a little suspicious about the stream performance, but thanks to a comment of Hulk, I realized that you need to warm up the lambda executions (run it at least twice) to get reasonable result. 我对流的性能有点怀疑,但是由于Hulk的评论,我意识到你需要预热lambda执行(至少运行两次)以获得合理的结果。

public class StreamTest {
    public static void main(String[] args) {
        // will include lambda warm up time
        java8test();

        java8test();

        java7test();
    }


    public static void java8test() {
        List<String> test = new ArrayList<>();
        test.add("--path=C:/log");
        test.add("--time=hourly");

        long start = System.nanoTime();
        List<String> result = test.stream().flatMap(e->{
            String[] array = e.split("=");
            return Stream.of(array);
        }).collect(Collectors.toList());

        long end = System.nanoTime();

        System.out.println("Java 8 style: " + (end-start) + "ns: " + result);
    }

    public static void java7test() {
        String[] test2 = {"--path=C:/log", "--time=hourly"};

        long start = System.nanoTime();
        test2 = String.join("=", test2).split("=");
        long end = System.nanoTime();
        System.out.println("old style: " + (end-start) + "ns:" + Arrays.toString(test2));
    }

}

Performance: 性能:

Java 8 style: 188154148ns: [--path, C:/log, --time, hourly]
Java 8 style: 129220ns: [--path, C:/log, --time, hourly]
old style: 364275ns:[--path, C:/log, --time, hourly]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM