【问题标题】:How to convert a Java 8 Stream to an Array?如何将 Java 8 流转换为数组?
【发布时间】:2014-05-29 12:42:03
【问题描述】:

将 Java 8 Stream 转换为数组的最简单/最短的方法是什么?

【问题讨论】:

  • 我建议您恢复回滚,因为问题更完整并且表明您已经尝试过。
  • @skiwi 谢谢!但我认为尝试的代码并没有真正为问题添加更多信息,并且没有人尖叫“向我们展示你的尝试”=)
  • @skiwi:虽然我通常对做我的家庭作业而不是我的问题大喊大叫,但这个特殊的问题对我来说似乎更清楚,没有任何额外的混乱。让我们保持整洁。
  • 可以在包的官方文档中找到很多答案和指导:docs.oracle.com/javase/8/docs/api/java/util/stream/…

标签: java arrays java-8 java-stream


【解决方案1】:

最简单的方法是使用带有数组构造函数引用的toArray(IntFunction<A[]> generator) 方法。这是在API documentation for the method 中建议的。

String[] stringArray = stringStream.toArray(String[]::new);

它所做的是找到一个接受整数(大小)作为参数并返回String[] 的方法,这正是new String[] 的(其中一个重载)所做的。

你也可以自己写IntFunction

Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);

IntFunction&lt;A[]&gt; generator 的目的是将数组大小的整数转换为新数组。

示例代码:

Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);

打印:

a
b
c

【讨论】:

  • 这里解释了 Array 构造函数引用为什么以及如何实际工作:stackoverflow.com/questions/29447561/…
  • "Zenexer 是对的,解决方案应该是:stream.toArray(String[]::new);" ...好吧,但是应该明白方法引用在逻辑和功能上等同于toArray(sz -&gt; new String[sz]),所以我不确定是否真的能说出解决方案应该或必须是什么。
  • @scottb sz -&gt; new String[sz] 创建了一个新函数,而构造函数引用却没有。我猜这取决于您对垃圾收集流失的重视程度。
  • @WORMSS 它没有。它(静态地!)创建了一个新的private 方法,它不会导致流失,并且两个版本都需要创建一个新对象。引用创建一个直接指向目标方法的对象;一个 lambda 创建一个指向生成的 private 的对象。由于缺乏间接性和更容易的 VM 优化,对构造函数的引用仍然应该表现得更好,但搅动与它无关。
  • @HTNW 你是对的,我很抱歉。事实上,当我第一次尝试这样做时,正是我尝试调试导致了导致流失的流失,所以我一直认为这就是它的样子。 (当这种情况发生时讨厌它)。
【解决方案2】:

如果您想从 Stream&lt;Integer&gt; 获取一个整数数组,其值从 1 到 10,您可以使用 IntStream

在这里,我们使用Stream.of 方法创建Stream,并使用mapToIntStream&lt;Integer&gt; 转换为IntStream。然后我们就可以调用IntStreamtoArray方法了。

Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream 
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array =  stream.mapToInt(x -> x).toArray();

这里是同样的事情,没有Stream&lt;Integer&gt;,只使用IntStream

int[]array2 =  IntStream.rangeClosed(1, 10).toArray();

【讨论】:

    【解决方案3】:

    您可以创建将流转换为数组的自定义收集器。

    public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
    {
        return Collectors.collectingAndThen( 
                      Collectors.toList(), 
                      list ->list.toArray( converter.apply( list.size() ) ) );
    }
    

    快速使用

    List<String> input = Arrays.asList( ..... );
    
    String[] result = input.stream().
             .collect( CustomCollectors.**toArray**( String[]::new ) );
    

    【讨论】:

    • 你为什么要用这个而不是Stream.toArray(IntFunction)
    • 我需要一个收集器来传递给 2-arg Collectors.groupingBy,以便我可以将某些属性映射到每个属性值的对象数组。这个答案给了我确切的答案。还有@DidierL。
    • 从Java 11开始,collectingAndThen中的finisher可以写成list -&gt; list.toArray(converter),因为添加了Collection.toArray​(IntFunction)
    【解决方案4】:
         Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
    
         Integer[] integers = stream.toArray(it->new Integer[it]);
    

    【讨论】:

      【解决方案5】:

      您可以使用这个简单的代码块将 java 8 流转换为数组:

       String[] myNewArray3 = myNewStream.toArray(String[]::new);
      

      但是让我们解释一下,首先,让我们创建一个包含三个值的字符串列表:

      String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};
      

      从给定的数组创建一个流:

      Stream<String> stringStream = Arrays.stream(stringList);
      

      我们现在可以对此流执行一些操作,例如:

      Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
      

      最后使用这些方法将其转换为 java 8 数组:

      1-经典方法(函数式接口)

      IntFunction<String[]> intFunction = new IntFunction<String[]>() {
          @Override
          public String[] apply(int value) {
              return new String[value];
          }
      };
      
      
      String[] myNewArray = myNewStream.toArray(intFunction);
      

      2 -Lambda 表达式

       String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);
      

      3- 方法参考

      String[] myNewArray3 = myNewStream.toArray(String[]::new);
      

      方法参考说明:

      这是编写 lambda 表达式的另一种方式,它与另一种方式严格等价。

      【讨论】:

        【解决方案6】:

        使用toArray(IntFunction&lt;A[]&gt; generator) 方法确实是一种非常优雅且安全的方法,可以将Stream 转换(或更准确地说,收集)为与Stream 相同类型的数组。

        但是,如果返回数组的类型不重要,那么简单地使用toArray() 方法既更容易更短。 例如:

            Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
            System.out.printf("%s, %s, %s!", args.toArray());
        

        【讨论】:

          【解决方案7】:

          将文本转换为字符串数组,其中每个值用逗号分隔,并修剪每个字段,例如:

          String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);
          

          【讨论】:

            【解决方案8】:
            Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
            
            int[] arr=   stream.mapToInt(x->x.intValue()).toArray();
            

            【讨论】:

              【解决方案9】:
              import java.util.List;
              import java.util.stream.Stream;
              
              class Main {
              
                  public static void main(String[] args) {
                      // Create a stream of strings from list of strings
                      Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();
              
                      // Convert stream to array by using toArray method
                      String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);
              
                      // Print results
                      for (String string : myArrayOfStrings) {
                          System.out.println(string);
                      }
                  }
              }
              

              在线试用:https://repl.it/@SmaMa/Stream-to-array

              【讨论】:

              • 你的答案和接受的答案有什么区别?
              • @LongNguyen 这是一个完整的例子,包括一个在线回放场景,而不仅仅是一个 sn-p。
              【解决方案10】:

              你可以这样使用收集器

                Stream<String> io = Stream.of("foo" , "lan" , "mql");
                io.collect(Collectors.toCollection(ArrayList<String>::new));
              

              【讨论】:

              • 问题是 [] 不是 ArrayList
              猜你喜欢
              • 2019-04-12
              • 2018-06-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-05-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多