如何将Java 8流转换为数组?


459

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

+2

我建议你恢复回滚的问题是更完整,更表明您曾经尝试过的东西。 15 4月. 142014-04-15 09:13:21

  0

@skiwi谢谢!但我认为尝试的代码并没有真正为问题添加更多信息,也没有人尖叫“向我们展示你的企图”,但= = 15 4月. 142014-04-15 09:20:32

+12

@skiwi:尽管我通常会对做我的作业 - 而不是我 - 问题,这个问题似乎对我来说更加清晰,没有任何额外的麻烦。让我们保持整洁。 16 4月. 142014-04-16 11:21:24

692

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

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

它能做什么,是发现,发生在一个整数(大小)作为参数的方法,并返回一个String[],这正是(的重载之一)new String[]一样。

你也可以写你自己的IntFunction

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

IntFunction<A[]> generator的目的是转换为整数,该数组的大小,到一个新的数组。

示例代码:

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

打印:

a 
b 
c 
+176

'String [] :: new'是一个好方法;在我看来,比拉姆达表达更直接。 18 12月. 142014-12-18 07:55:54

+11

Zenexer是正确的,解决方案应该是: 'stream.toArray(String [] :: new);' 01 10月. 152015-10-01 13:01:08

+4

这里解释了为什么以及如何实现数组构造函数参考:http://stackoverflow.com/问题/ 29447561/how-do-java-8-array-constructor-references-work 12 9月. 162016-09-12 18:16:38

  0

*“Zenexer是正确的,解决方案应该是:stream.toArray(String [] :: new);”* ...好吧好吧,但应该明白,方法引用在逻辑上和功能上等同于'toArray(sz - > new String [sz])',所以我不确定是否可以真正说出解决方案应该或应该是什么。 20 4月. 172017-04-20 14:16:02

  0

数组构造函数的参考更加简洁。 'toArray()'方法的文档引用了它的简洁性,并且包括它在唯一示例中的使用。当答案结束时,我在一读时错过了。将其移到顶部,在细节上方,以便其他人不会错过它。 01 5月. 172017-05-01 19:44:05

+2

@scottb'sz - > new String [sz]'产生一个新的函数,而构造函数引用不会。这取决于你估价多少垃圾收集流失我猜。 18 8月. 172017-08-18 09:19:42

+1

@WORMSS它没有。它(静态地!)创建一个新的'private' *方法*,它不会导致客户流失,并且*两个*版本都需要创建一个新对象。引用创建一个直接指向目标方法的对象; lambda会创建一个指向生成的“private”对象的对象。对构造函数的引用仍然应该更好,因为缺乏间接性和更简单的虚拟机优化,但搅动与它无关。 29 10月. 172017-10-29 23:54:01

  0

@HTNW你是对的,我道歉。事实上,我尝试去调试,这是我第一次尝试这样做时导致流失的流失,所以我一直在我的脑海里说,事情就是这样。 (当它发生时,恨它)。 30 10月. 172017-10-30 08:38:59


17

如果你想获得int数组,其值形式1至10,从流,有IntStream在您的处置。

这里我们用Stream.of方法创建Stream并使用mapToInt将Stream转换为IntStream。然后我们可以调用IntStream的toArray方法。

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

这里是同样的事情,而不流,仅使用IntStream

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

2

您可以创建自定义收集器转换流阵列。

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

0
 Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6); 

    Integer[] integers = stream.toArray(it->new Integer[it]); 

0

您可以在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表达式,它是严格地等同于其他的另一种方式。


2

使用toArray(IntFunction<A[]> generator)方法确实是将Stream(或更准确地说,收集)转换为相同类型Stream的数组的非常优雅和安全的方法。

但是,如果返回的数组类型不重要,则只需使用toArray()方法更容易缩短。 例如:

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