Java8:分组、计数和加入

Java8:分组、计数和加入,java,java-stream,Java,Java Stream,我正在尝试一段我不能完全正确的代码。我有一个列表,上面有1000个字符串条目(每个条目3-10个字符),我将它们收集到一个逗号分隔的字符串中。如果结果字符串中字符的总大小超过8100,我需要拆分列表并创建两个逗号分隔的字符串(或3,或8100的任何因子)。我知道这需要一个groupby,但我的语法不起作用 因此,我的第一个问题是,如何确定列表中的字符总数,以及如何对列表进行分组,使每组列表中的字符数不超过8100个?这就是我到目前为止所做的: AtomicInteger counter = ne

我正在尝试一段我不能完全正确的代码。我有一个列表,上面有1000个字符串条目(每个条目3-10个字符),我将它们收集到一个逗号分隔的字符串中。如果结果字符串中字符的总大小超过8100,我需要拆分列表并创建两个逗号分隔的字符串(或3,或8100的任何因子)。我知道这需要一个
groupby
,但我的语法不起作用

因此,我的第一个问题是,如何确定列表中的字符总数,以及如何对列表进行分组,使每组列表中的字符数不超过8100个?这就是我到目前为止所做的:

AtomicInteger counter = new AtomicInteger();
String codes = configInfos.stream()
    .map(ConfigInfo::getCode)
    .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / 8100))

这需要用流来解决吗

否则我会这样解决:

String [] array = configInfos
    .stream()
    .map( ConfigInfo::getCode )
    .toArray( String []::new );
List<String> codes = new ArrayList<>();
StringJoiner joiner = new StringJoiner( "," );
for( String s : array )
{
    if( joiner.length() + 1 + s.length() > 8100 )
    {
        codes.add( joiner.toString() );
        joiner = new StringJoiner( "," );
    }
    joiner.add( s );
}
if( joiner.length() > 0 ) codes.add( joiner.toString() );
String[]array=configInfos
.stream()
.map(ConfigInfo::getCode)
.toArray(字符串[]::新建);
列表代码=新的ArrayList();
细木工=新细木工(“,”);
for(字符串s:数组)
{
if(细木工长度()+1+s长度()>8100)
{
add(joiner.toString());
细木工=新的细木工(“,”);
}
加入者。添加(s);
}
if(joiner.length()>0)code.add(joiner.toString());
但我必须承认,我不知道如何用流解决这个问题…

Edit:不要用流解决这个问题 我需要在拆分时维护字符串。它必须看起来像 原始列表,列表1为“条目”,“是”。清单2将是 “三”,“最多”。清单3将是“十”,“字符”,等等

流操作不适合您的任务。我建议您使用一个经典的循环来获得最清晰、最容易维护的代码

原始答案:Intstream.range() 我不确定这是你真正想要的。如果您更喜欢使用流,下面是我的尝试

    final int maxSubstringLength = 9; // 8100

    List<String> entries = List.of("Entries", "are", "three", "upto", "ten", "chars", "each");
    String totalString = entries.stream().collect(Collectors.joining(","));

    // round up in the division
    int substringCount = (totalString.length() + maxSubstringLength - 1) / maxSubstringLength;
    List<String> substrings = IntStream.range(0, substringCount)
            .mapToObj(i -> totalString.substring(i * maxSubstringLength, Math.min((i + 1) * maxSubstringLength, totalString.length())))
            .collect(Collectors.toList());

    substrings.forEach(System.out::println);

对于很长的字符串,只需将8100作为最大子字符串长度,在此处我将9作为示例。这是否回答了您的问题?“分组依据”并非真正用于“将数据集拆分为单独的组”
groupingBy
用于识别数据集中具有您选择的公共属性的子集(通常用于聚合:如:按首字母计数单词,其中单词数据集中的所有首字母决定每个单词的组)。在这种情况下,我建议您使用一个循环和一个
int
变量,您可以在每次达到8100时重置该变量。你也可以用流做类似的事情,但这有点不自然。你是在用delimeter加入Char之后,还是在加入Char之前计算Char?换言之,你计算结果字符串中的逗号吗?我在连接后计算整个字符串。是的,我包括逗号。但是我需要在分割时维护字符串。它必须看起来像原始列表,列表1是“条目”,“是”。清单2将是“三”,“最多”。清单3将是“十”,“字符”,等等。这看起来很接近!!不过,为了可维护性,我想使用流。@user1660256“使用流进行可维护性”毫无意义。代码不会因为您使用了流API而变得更易于维护。流更为体贴和可读。对我来说很有道理。@user1660256你错了。在某些情况下,流更具可读性。在这种情况下,它们将导致代码非常不可读。现在还没有什么灵丹妙药,我们必须根据情况选择我们的工具。这个答案中的代码非常优雅。即使这个答案在语法上不正确,我也会接受它。
Entries,a
re,three,
upto,ten,
chars,eac
h