[英]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.
只需获得一个现有的解决方案,请参阅此处的首发。
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#stream
( documentation )将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#split
( documentation )将参数拆分为=
,然后使用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
方法( 文档 )。
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.