Java 转换流<;IntStream>;到单个IntStream

Java 转换流<;IntStream>;到单个IntStream,java,java-8,java-stream,Java,Java 8,Java Stream,我想将列表转换为IntStream。假设我的列表类似于[“abc”,“de”,“fghi”]。然后我想要的IntStream就像1,1,1,2,2,3,3,3,3。(编号i在IntStream中出现的次数取决于给定列表中第个字符串的长度) 我为此编写了以下方法(它不会编译): 私有静态IntStream getSingleIntStream(列表){ final AtomicInteger AtomicInteger=新的AtomicInteger(); return list.stream()

我想将
列表
转换为
IntStream
。假设我的列表类似于
[“abc”,“de”,“fghi”]
。然后我想要的
IntStream
就像
1,1,1,2,2,3,3,3,3
。(编号
i
IntStream
中出现的次数取决于给定列表中第个字符串的长度)

我为此编写了以下方法(它不会编译):

私有静态IntStream getSingleIntStream(列表){
final AtomicInteger AtomicInteger=新的AtomicInteger();
return list.stream()
.map(str->{
atomicInteger.incrementAndGet();
返回IntStream.range(0,str.length())
.map(i->atomicInteger.get());
});//现在我不明白如何将此流转换为单个IntStream
}
但是我不明白如何转换我可以将
转换为单个
IntStream
。(我猜我们可以用
flatMap
,但我不知道如何使用它。)


我正在使用
IntStream
而不是
Stream
,以避免自动装箱,并使整个系统更高效。

扩展@JB\u Nizet的注释

我需要使用的方法是

私有静态IntStream getSingleIntStream(列表){
final AtomicInteger AtomicInteger=新的AtomicInteger();
return list.stream()
.flatMapToInt(str->{
atomicInteger.incrementAndGet();
返回IntStream.range(0,str.length())
.map(i->atomicInteger.get());
});
}

解决方案是使用
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());
        });
}
我假设您想对每个
字符串中的每个字符进行编号:

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
私有静态IntStream getSingleIntStream(列表){
AtomicInteger AtomicInteger=新的AtomicInteger();
return list.stream()
.flatMapToInt(str->IntStream.range(0,str.length())
.map(i->atomicInteger.incrementAndGet());
}
// 1 2 3

另一种解决方案如下:

IntStream result =  IntStream.range(0,list.size())
                             .flatMap(i-> IntStream.range(0, list.get(i)
                                                                 .length())
                                                   .map(j->i+1));

关于
flatMap
,您是绝对正确的,正如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));
}
[1,1,1,2,2,3,3,3,3]


当您需要流中某个元素的索引时,通常的技巧是从索引的
IntStream
开始,并在流管道中从索引中查找元素(
list.get(i-1)
)。在本例中,我(非传统地)使用基于1的索引,因为您希望得到的数字从1开始。因此,我们需要在列表查找中减去1。

您能告诉我们您想要实现的目标的更多细节吗?使用AtomicInteger表示您可能正在以不必要的方式执行某些操作@GrzegorzPiwowarek我只想获取
IntStream
。学习Java-8的流API比做一些有用的事情更重要。但是如果您能做一些我们不使用
AtomicInteger
的事情,我将非常感激。我也觉得很难看。是的,但是你想实现什么?我看到您只需丢弃输入列表中的所有字符串,并将其替换为AtomicInteger生成的序列?这就是我要做的,字符串的内容并不重要,而是每个字符串的长度都很重要,在此基础上,我需要生成一个序列。这个
IntStream.range(0,list.size())如何.flatMap(i->IntStream.range(0,list.get(i).length()).map(j->i+1))我想我几乎用
列表I);}写了一个类似的版本
我显然更喜欢这个,而不是使用
AtomicInteger
的不太好的副作用。我发现一个更自然的变体是
IntStream.range(0,list.size()).flatMap(index->list.get(index.chars().map(ch->index+1))
,但可能效率不高,而且肯定是口味问题。@OleV.V
…list.get(index).chars().map(ch->index+1).
它比我的更简洁。请随意采用。很高兴你喜欢。
private static IntStream getSingleIntStream(List<String> list) {
    return IntStream.rangeClosed(1, list.size())
            .flatMap(i -> list.get(i - 1).chars().map(ch -> i));
}
    List<String> list = List.of("abc", "de", "fghi");
    int[] nums = getSingleIntStream(list).toArray();
    System.out.println(Arrays.toString(nums));