为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕斯王 2021-10-13 15:53:48
我的问题受到这个问题的启发,但旨在使用 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?
查看完整描述

3 回答

?
慕村9548890

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());


查看完整回答
反对 回复 2021-10-13
?
肥皂起泡泡

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


查看完整回答
反对 回复 2021-10-13
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

为什么 x 被报告为一个 ArrayList 但我不能声明 x 是一个 ArrayList。

因为

  1. collect(...)根据 的结果类型返回静态推断类型Collectors.toList()

  2. 也就是说(在这种情况下)Collector<String,?,List<String>>......根据Collectors javadoc

实际对象是 an 的事实ArrayList是一个实现细节,可以想象在 Java 的未来版本中可能会发生变化。

有没有更好的方法使用流将这个数字字符串转换为整数列表?

我会留给其他人说。但是,我认为一个更简单/更干净的方法是不使用流来完成这项任务。

    String input = "1 2 3 4 5";
        var x = new ArrayList<>(Arrays.asList(input.split(" ")));

上面的代码比我见过的基于流的版本更简单,而且很可能更有效。


查看完整回答
反对 回复 2021-10-13
  • 3 回答
  • 0 关注
  • 321 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信