How to Convert a Java 8 Stream to an Array?
将Java 8 EDCOX1×0的数组转换成数组最简单/最短的方法是什么?
- 我建议您恢复回滚,因为问题更完整,并且显示您尝试了一些操作。
- @斯基维,谢谢!但是我认为尝试的代码并没有给这个问题增加更多的信息,而且还没有人尖叫"展示你的尝试"。
- @斯基维:虽然我通常在做作业时大喊,而不是问我问题,但这个问题对我来说似乎更清楚,没有任何额外的混乱。让我们保持整洁。
最简单的方法是使用带数组构造函数引用的toArray(IntFunction generator)方法。在API文档中建议使用这种方法。
它的作用是找到一个以整数(大小)为参数并返回String[]的方法,这正是new String[]所做的(重载之一)。
你也可以写自己的IntFunction:
1 2
| Stream <String > stringStream = ... ;
String[] stringArray = stringStream. toArray(size -> new String[size ]); |
号
IntFunction generator的目的是将数组大小的整数转换为新的数组。
示例代码:
1 2 3
| Stream <String > stringStream = Stream. of("a", "b", "c");
String[] stringArray = stringStream. toArray(size -> new String[size ]);
Arrays. stream(stringArray ). forEach(System. out::println ); |
印刷品:
。
- 下面是数组构造函数引用实际工作的原因和方式的解释:stackoverflow.com/questions/29447561/&hellip;
- "ZenExer是正确的,解决方案应该是:stream.toArray(string[]::new);"..好吧,但是我们应该理解方法引用在逻辑上和功能上等同于toArray(sz -> new String[sz]),所以我不确定我们是否真的可以说出解决方案应该或必须是什么。
- 数组构造函数引用更简洁。toArray()方法的文档引用了它的简洁性,并将其用于唯一的示例中。当它被钉在答案的末尾时,我在第一次阅读时就错过了。把它移到细节上面的顶部,这样别人就不会错过它了。
- @scottb sz -> new String[sz]创建了一个新函数,其中as-constructor引用没有。我想这取决于你对垃圾回收的重视程度。
- @它不会。它(静态!)生成一个新的private方法,该方法不能导致用户流失,两个版本都需要创建一个新对象。引用创建一个直接指向目标方法的对象;lambda创建一个指向生成的private1的对象。对于构造函数的引用,由于缺少间接寻址和更容易的VM优化,仍然应该表现得更好,但搅动与此无关。
- @你说得对,我道歉。我第一次尝试调试的时候,它实际上是造成搅动的原因,所以我把它卡在了我的脑子里,这就是它的原形。(当这种情况发生时讨厌它)。
如果您想从一个流中获得一个int数组,其值形式为1到10,那么您可以使用intstream。
在这里,我们使用stream.of方法创建一个流,并使用maptoint将该流转换为intstream。然后我们可以调用intstream的toarray方法。
1 2 3 4
| 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
1
| int[]array2 = IntStream.rangeClosed(1, 10).toArray(); |
。
可以使用这个简单的代码块将Java 8流转换成数组:
但让我们进一步解释一下,首先,让我们创建一个包含三个值的字符串列表:
1
| String[] stringList = {"Bachiri", "Taoufiq", "Abderrahman"}; |
。
从给定数组创建流:
1
| Stream <String > stringStream = Arrays. stream(stringList ); |
号
我们现在可以在此流上执行一些操作,例如:
1
| Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase()); |
号
最后使用这些方法将其转换为Java 8数组:
1-经典方法(功能接口)
1 2 3 4 5 6 7 8 9
| IntFunction <String[]> intFunction = new IntFunction <String[]>() {
@Override
public String[] apply (int value ) {
return new String[value ];
}
};
String[] myNewArray = myNewStream. toArray(intFunction ); |
号
2-lambda表达式
1
| String[] myNewArray2 = myNewStream. toArray(value -> new String[value ]); |
号
3-方法参考
号
方法参考说明:
这是编写lambda表达式的另一种方法,它严格等价于另一个表达式。
将文本转换为字符串数组,其中用逗号分隔每个值,并修剪每个字段,例如:
号
可以创建将流转换为数组的自定义收集器。
1 2 3 4 5 6
| public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
} |
。
快速使用
1 2 3 4
| List <String > input = Arrays. asList( ..... );
String[] result = input. stream().
. collect( CustomCollectors. **toArray **( String[]::new ) ); |
- 为什么要用这个来代替stream.toarray(intfunction)?
- 我需要一个收集器传递给2-arg Collectors.groupingBy,这样我就可以将一些属性映射到每个属性值的对象数组。这个答案给了我确切的答案。还有@didierl。
使用toArray(IntFunction generator)方法将流转换(或更准确地收集)为同一类型的流的数组确实是一种非常优雅和安全的方法。
但是,如果返回的数组的类型不重要,那么简单地使用toArray()方法既简单又短。例如:
1 2
| Stream <Object > args = Stream. of(BigDecimal. ONE, "Two", 3);
System. out. printf("%s, %s, %s!", args. toArray()); |
号
1 2 3
| Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
int[] arr= stream.mapToInt(x->x.intValue()).toArray(); |
号
1 2 3
| Stream <Integer > stream = Stream. of(1, 2, 3, 4, 5, 6);
Integer[] integers = stream. toArray(it ->new Integer[it ]); |
。
你可以用几种方法来实现,所有的方法在技术上都是一样的,但是使用lambda可以简化一些代码。假设我们首先用字符串初始化一个列表,称之为persons。
1 2
| List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream(); |
号
现在您可以使用以下任何一种方法。
使用lambda表达式创建具有定义大小的新StringArray。
string[]stringarray=stream.toarray(size->new string[size]);
直接使用方法引用。
string[]stringarray=stream.toarray(string[]::new);