3 回答
TA贡献1884条经验 获得超4个赞
您可以创建一个ArrayList,但不应:
ArrayList<Integer> x =
stream.map(Integer::valueOf)
.collect(Collectors.toCollection(ArrayList::new));
重构:
List<Integer> x =
Arrays.stream(input.split(" "))
.map(Integer::valueOf)
.collect(Collectors.toList());
或者,使用Pattern.splitAsStream:
List<Integer> x =
Pattern.compile(" ").splitAsStream("1 2 3 4 5")
.map(Integer::valueOf)
.collect(Collectors.toList());
TA贡献1829条经验 获得超6个赞
首先,你Stream是生的。使用原始类型意味着使用类型参数的任何内容都将被擦除到其上限,此处为Object。所以map返回另一个 rawStream并collect返回一个Object. 轻松修复:Stream<String>。
Stream<String> stream = Arrays.stream( input.split( " " ) );
其次,Collectors.toList是指定返回List<T>,或者List<String>这里。
对返回的类型、可变性、可序列化或线程安全性没有任何保证List;如果List需要对返回的进行更多控制,请使用toCollection(Supplier).
如果您不满意List并且您绝对需要一个ArrayList,请提供一个:
.collect(Collectors.toCollection(ArrayList::new));
顺便说一句,您可以替换 lambda 表达式
s -> Integer.valueOf( ( String ) s )
与方法参考
Integer::valueOf
进行这些更改后,您的代码可能如下所示:
String input = "1 2 3 4 5";
Stream< String > stream = Arrays.stream( input.split( " " ) );
List< Integer > x = stream.map( Integer::valueOf ).collect( Collectors.toList() );
或者,如果您坚持精确ArrayList而不是List,请执行以下操作:
String input = "1 2 3 4 5";
Stream< String > stream = Arrays.stream( input.split( " " ) );
ArrayList< Integer > x = stream.map( Integer::valueOf ).collect( Collectors.toCollection( ArrayList::new ) );
一旦进行了这些更改,这似乎是将包含以空格分隔的整数的字符串转换为ArrayList<Integer>. 一个小的改进是将split正则表达式参数更改为"\\s+", 以表示一个或多个空白字符。如果"1 2"到达,数字之间有多个空格,这将防止空字符串在空格字符之间匹配。
TA贡献1842条经验 获得超12个赞
为什么 x 被报告为一个 ArrayList 但我不能声明 x 是一个 ArrayList。
因为
collect(...)
根据 的结果类型返回静态推断类型Collectors.toList()
。也就是说(在这种情况下)
Collector<String,?,List<String>>
......根据Collectors
javadoc。
实际对象是 an 的事实ArrayList
是一个实现细节,可以想象在 Java 的未来版本中可能会发生变化。
有没有更好的方法使用流将这个数字字符串转换为整数列表?
我会留给其他人说。但是,我认为一个更简单/更干净的方法是不使用流来完成这项任务。
String input = "1 2 3 4 5"; var x = new ArrayList<>(Arrays.asList(input.split(" ")));
上面的代码比我见过的基于流的版本更简单,而且很可能更有效。
添加回答
举报