猿问

使用 Java Stream 将一串数字解析为 Integer 对象列表

我的问题受到这个问题的启发,但旨在使用 Java Streams 来获得 a List<Integer>。


我有这样的代码。它似乎正在返回一个ArrayList,大概是ArrayList<Integer>. 但是编译器拒绝让我这样声明结果。


String input = "1 2 3 4 5";

Stream stream = Arrays.stream( input.split( " " ) );

var x = stream.map( s -> Integer.valueOf( ( String ) s ) ).collect( Collectors.toList() );

这在使用var最新 Java 版本的新功能时运行。


System.out.println( x.getClass() );

System.out.println( x );

类 java.util.ArrayList


[1, 2, 3, 4, 5]


我有两个问题:


为什么被x报告为一个ArrayList但我不能声明x为一个 ArrayList(错误:不兼容的类型),例如:

ArrayList<Integer> x = stream.map( s -> Integer.valueOf( ( String ) s ) ).collect( Collectors.toList() );

有没有更好的方法来使用流将这串数字转换为 a Listof Integer?


慕斯王
浏览 322回答 3
3回答

慕村9548890

您可以创建一个ArrayList,但不应:ArrayList<Integer> x =&nbsp; &nbsp; stream.map(Integer::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toCollection(ArrayList::new));重构:List<Integer> x =&nbsp; &nbsp; Arrays.stream(input.split(" "))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(Integer::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());或者,使用Pattern.splitAsStream:List<Integer> x =&nbsp; &nbsp; Pattern.compile(" ").splitAsStream("1 2 3 4 5")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.map(Integer::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collectors.toList());

肥皂起泡泡

首先,你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&nbsp; 2"到达,数字之间有多个空格,这将防止空字符串在空格字符之间匹配。

红颜莎娜

为什么 x 被报告为一个 ArrayList 但我不能声明 x 是一个 ArrayList。因为collect(...)根据 的结果类型返回静态推断类型Collectors.toList()。也就是说(在这种情况下)Collector<String,?,List<String>>......根据Collectors&nbsp;javadoc。实际对象是 an 的事实ArrayList是一个实现细节,可以想象在 Java 的未来版本中可能会发生变化。有没有更好的方法使用流将这个数字字符串转换为整数列表?我会留给其他人说。但是,我认为一个更简单/更干净的方法是不使用流来完成这项任务。&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;input&nbsp;=&nbsp;"1&nbsp;2&nbsp;3&nbsp;4&nbsp;5"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;x&nbsp;=&nbsp;new&nbsp;ArrayList<>(Arrays.asList(input.split("&nbsp;")));上面的代码比我见过的基于流的版本更简单,而且很可能更有效。
随时随地看视频慕课网APP

相关分类

Java
我要回答