我想将List<String>
转换为IntStream
。假设我的列表像["abc", "de", "fghi"]
。然后,我想要的IntStream
就像1,1,1,2,2,3,3,3,3
。 (在i
中出现数字IntStream
的次数取决于给定列表中第i
个字符串的长度)
我为此编写了以下方法(它不会编译):
private static IntStream getSingleIntStream(List<String> list) {
final AtomicInteger atomicInteger = new AtomicInteger();
return list.stream()
.map(str -> {
atomicInteger.incrementAndGet();
return IntStream.range(0, str.length())
.map(i -> atomicInteger.get());
}); // Now I don't understand how can I convert this Stream<IntStream> to a single IntStream
}
但是我不知道该如何转换才能将Stream<IntStream>
转换为单个IntStream
。 (我的猜测是我们可以以某种方式使用flatMap
,但我不完全了解如何使用它。)
我使用IntStream
而不是Stream<Integer>
来避免自动装箱,并使整个系统更高效。
答案 0 :(得分:6)
另一个解决方案是这样的:
IntStream result = IntStream.range(0,list.size())
.flatMap(i-> IntStream.range(0, list.get(i)
.length())
.map(j->i+1));
答案 1 :(得分:2)
扩展@JB_Nizet的评论
我需要使用的方法是flatMapToInt。
private static IntStream getSingleIntStream(List<String> list) {
final AtomicInteger atomicInteger = new AtomicInteger();
return list.stream()
.flatMapToInt(str -> {
atomicInteger.incrementAndGet();
return IntStream.range(0, str.length())
.map(i -> atomicInteger.get());
});
}
答案 2 :(得分:1)
解决方案是使用flatMapToInt
:
private static IntStream getSingleIntStream(List<String> list) {
final AtomicInteger atomicInteger = new AtomicInteger();
return list.stream()
.flatMapToInt(str -> {
atomicInteger.incrementAndGet();
return IntStream.range(0, str.length())
.map(i -> atomicInteger.get());
});
}
但是我会重新考虑您想要在这里实现的目标。现在,初始列表中的每个String
都将替换为AtomicInteger
中的一个数字(并且每个String都会重复String.length()次):
getSingleIntStream(Arrays.asList("a", "bc")).forEach(System.out::println); // 1 2 2
我假设您想为每个String
中的每个字符编号:
private static IntStream getSingleIntStream(List<String> list) {
AtomicInteger atomicInteger = new AtomicInteger();
return list.stream()
.flatMapToInt(str -> IntStream.range(0, str.length())
.map(i -> atomicInteger.incrementAndGet()));
}
// 1 2 3
答案 3 :(得分:1)
您对flatMap
绝对是正确的,正如哈迪·J(Hadi J)在一个好的答案中所表明的那样。我只想提供相同的变量:
private static IntStream getSingleIntStream(List<String> list) {
return IntStream.rangeClosed(1, list.size())
.flatMap(i -> list.get(i - 1).chars().map(ch -> i));
}
您可能会发现此版本更为自然或简洁。在任何情况下,两种版本都具有避免AtomicInteger
以及流管道对其产生副作用的优点。流管道应无副作用。
我们也可以看到它的作用:
List<String> list = List.of("abc", "de", "fghi");
int[] nums = getSingleIntStream(list).toArray();
System.out.println(Arrays.toString(nums));
[1、1、1、2、2、3、3、3、3]
当您需要流中元素的索引时,一般的技巧是从IntStream
个索引开始,然后在流管道内部从索引中查找元素({{1 }})。在这种情况下,我(非常规地)使用基于1的索引,因为您希望得到的数字从1开始。因此我们需要在列表查找中减去1。