代码之家  ›  专栏  ›  技术社区  ›  Basil Bourque

使用Java流将数字字符串解析为整数对象列表

  •  0
  • Basil Bourque  · 技术社区  · 6 年前

    我的问题是受 this Question ,但旨在使用Java流来实现 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(错误:类型不兼容),例如:
      ArrayList<Integer> x = stream.map( s -> Integer.valueOf( ( String ) s ) ).collect( Collectors.toList() );
    • 有没有更好的方法使用流来将这个数字串转换成 List Integer
    4 回复  |  直到 6 年前
        1
  •  3
  •   Basil Bourque    6 年前

    首先,你的 Stream 是生的。使用原始类型意味着任何使用类型参数的内容都会被删除到其上限,这里是 Object map 返回另一个原始 溪流 collect 返回一个 . 易于修复: Stream<String> .

    Stream<String> stream = Arrays.stream( input.split( " " ) );
    

    其次, Collectors.toList 指定为返回 List<T> ,或 List<String> 在这里。

    List 是必需的,请使用 toCollection(Supplier)

    如果你不满意 列表 你绝对需要一个 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() );
    

    阵列列表 而不是 列表

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

        2
  •  3
  •   Oleksandr Pyrohov Andreas    6 年前

    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());
    
        3
  •  1
  •   Solace    6 年前
    List<Integer> list = Arrays.stream("1 2 3 4 5".split(" ")).map(s -> Integer.valueOf(s)).collect(Collectors.toList());
    

    collectors source code :“对于类型、可变性,

        4
  •  1
  •   Stephen C    6 年前

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

    因为

    1. collect(...) Collectors.toList() .
    2. Collector<String,​?,​List<String>> ... 根据 Collectors javadoc

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

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

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

    上面的代码比我见过的基于流的版本更简单,也更有效。