将数组/字符串列表转换为数组/整数列表的 Lambda 表达式
Posted
技术标签:
【中文标题】将数组/字符串列表转换为数组/整数列表的 Lambda 表达式【英文标题】:Lambda expression to convert array/List of String to array/List of Integers 【发布时间】:2014-05-28 06:18:28 【问题描述】:由于 Java 8 带有强大的 lambda 表达式,
我想编写一个函数来将字符串列表/数组转换为整数、浮点数、双精度等数组/列表。
在普通的Java中,它就像
一样简单for(String str : strList)
intList.add(Integer.valueOf(str));
但是,给定要转换为整数数组的字符串数组,我如何使用 lambda 实现相同的效果。
【问题讨论】:
【参考方案1】:我使用带有 Lambda 操作的 maptoInt() 将字符串转换为整数
int[] arr = Arrays.stream(stringArray).mapToInt(item -> Integer.parseInt(item)).toArray();
【讨论】:
【参考方案2】:我在之前的答案中没有找到它,所以,对于 Java 8 和流:
将String[]
转换为Integer[]
:
Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)
【讨论】:
【参考方案3】:Arrays.toString(int []) 对我有用。
【讨论】:
我没有回答这个问题:“如何使用 lambdas 实现这一点”。【参考方案4】:对于列表:
List<Integer> intList
= stringList.stream().map(Integer::valueOf).collect(Collectors.toList());
对于数组:
int[] intArray = Arrays.stream(stringArray).mapToInt(Integer::valueOf).toArray();
【讨论】:
【参考方案5】:你也可以用,
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
Integer[] array = list.stream()
.map( v -> Integer.valueOf(v))
.toArray(Integer[]::new);
【讨论】:
【参考方案6】:另外 - 控制字符串数组何时没有元素:
Arrays.stream(from).filter(t -> (t != null)&&!("".equals(t))).map(func).toArray(generator)
【讨论】:
【参考方案7】:List<Integer> intList = strList.stream()
.map(Integer::valueOf)
.collect(Collectors.toList());
【讨论】:
你能解释一下吗? 这是将字符串列表转换为流,然后将列表中的每个元素映射/转换为整数,然后收集到列表中。 这应该是公认的答案,因为 lambdas(原始问题要求 lambda 表达式)的目的是避免定义新函数。最重要的是,这个答案优雅地使用了现有的 Integer::valueOf 函数【参考方案8】:不需要来自已接受答案的辅助方法。 Streams 可以与 lambda 一起使用,或者通常使用 Method References 缩短。流支持功能操作。 map()
转换元素,collect(...)
或 toArray()
将流包装回数组或集合中。
Venkat Subramaniam's talk (video) 解释得比我好。
1 将List<String>
转换为List<Integer>
List<String> l1 = Arrays.asList("1", "2", "3");
List<Integer> r1 = l1.stream().map(Integer::parseInt).collect(Collectors.toList());
// the longer full lambda version:
List<Integer> r1 = l1.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());
2 将List<String>
转换为int[]
int[] r2 = l1.stream().mapToInt(Integer::parseInt).toArray();
3 将String[]
转换为List<Integer>
String[] a1 = "4", "5", "6";
List<Integer> r3 = Stream.of(a1).map(Integer::parseInt).collect(Collectors.toList());
4 将String[]
转换为int[]
int[] r4 = Stream.of(a1).mapToInt(Integer::parseInt).toArray();
5 将String[]
转换为List<Double>
List<Double> r5 = Stream.of(a1).map(Double::parseDouble).collect(Collectors.toList());
6(奖励)将int[]
转换为String[]
int[] a2 = 7, 8, 9;
String[] r6 = Arrays.stream(a2).mapToObj(Integer::toString).toArray(String[]::new);
当然还有更多的变化。
另见Ideone version of these examples。可以点击fork然后run在浏览器中运行。
【讨论】:
【参考方案9】:您可以创建辅助方法,使用stream
上的map
操作将T
类型的列表(数组)转换为U
类型的列表(数组)。
//for lists
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func)
return from.stream().map(func).collect(Collectors.toList());
//for arrays
public static <T, U> U[] convertArray(T[] from,
Function<T, U> func,
IntFunction<U[]> generator)
return Arrays.stream(from).map(func).toArray(generator);
并像这样使用它:
//for lists
List<String> stringList = Arrays.asList("1","2","3");
List<Integer> integerList = convertList(stringList, s -> Integer.parseInt(s));
//for arrays
String[] stringArr = "1","2","3";
Double[] doubleArr = convertArray(stringArr, Double::parseDouble, Double[]::new);
请注意
s -> Integer.parseInt(s)
可以替换为Integer::parseInt
(参见Method references)
【讨论】:
如果你使用 Guava,你也可以使用Lists.transform()
。
很好的例子。该功能使代码更加通用和强大。谢谢!!!【参考方案10】:
编辑:
正如 cmets 中所指出的,这是一个更简单的版本:
Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
这样我们就可以跳过与列表之间的整个转换。
我找到了另一种单行解决方案,但它仍然很慢(比 for 循环花费大约 100 倍 - 在 6000 个 0 的数组上测试)
String[] stringArray = ...
int[] out= Arrays.asList(stringArray).stream().map(Integer::parseInt).mapToInt(i->i).toArray();
这是做什么的:
-
Arrays.asList() 将数组转换为列表
.stream 将其转换为 Stream(需要执行映射)
.map(Integer::parseInt) 将流中的所有元素转换为整数
.mapToInt(i->i) 将所有整数转换为整数(如果您只需要整数,则不必这样做)
.toArray() 将 Stream 转换回数组
【讨论】:
您不需要步骤 1 和 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
以上是关于将数组/字符串列表转换为数组/整数列表的 Lambda 表达式的主要内容,如果未能解决你的问题,请参考以下文章