How to convert String [] args with section "=" in java 8

I need to convert

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

at

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

How can I do this in Java 8 in an elegant way?

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);
+4
source share
6 answers
String[] result = Stream.of(args)
        .flatMap(a -> Stream.of(a.split("=")))
        .toArray(String[]::new);
+9
source

The rest of the answers are all subtle technically, but the real answer is: do not.

Do not reinvent the wheel. Parsing command line options are actually complex. Regardless of what you came up with for the first stage, but assuming that we are talking about something that is intended for the latter, and good enough to attract users, sooner or later you will be more and more engaged in considering options .

: , - (, , ), , . , . .

+6

Java 8, Stream API ().

args Stream<String>, Arrays#stream (documentation). = String#split (), array, Stream#toArray ().

split ( ), Stream. Stream<String[]> , Stream<String>. , Stream#flatMap ().


, :

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

, Pattern#splitAsStream ():

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

, .

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

argument.split("=", 2).

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

I was a little suspicious of the performance of the stream, but thanks to Hulk's comment, I realized that you need to warm up the lambda execution (run it at least twice) to get a reasonable result.

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]
0
source

Source: https://habr.com/ru/post/1689902/


All Articles