将字符数组转换为多个字符串

3

我可以帮您将一个字符数组转换为特定大小的多行。例如,考虑以下这个字符数组:

char[] bases = new char[]{'a', 'c', 'c', 't', 'a', 'c', 'a', 't', 'a', 'c', 'c', 't', 'a', 'c', 'a', 't'};

如果尺寸为5,预期输出结果如下:

accta
catac
ctaca

我目前正在使用以下代码:

我目前正在使用以下代码:

    int ls = 5; 
    String str = ""; 
    for (int i = 1; i < bases.length; i++) {
        str += bases[i - 1];
        if (i%ls == 0) {
            str += '\n';
        }
    }

在Java 8中,是否有一些内置函数可以实现这个功能?解决这个问题是否有更好的方法?

一个HTML元素?这看起来更像是DNA。 - Willem Van Onsem
我不明白HTML与此有什么关系。 - Thomas
2
new String(bases, 0, 5)new String(bases, 5, 10)等。 - Andy Turner
抱歉,忘记更新标题了,现在应该更好了。 - felix
1
多个字符串?还是每5个字符换行的单个字符串? - Andy Turner
显示剩余2条评论
5个回答

5
您可以将char[]转换为字符串,然后可以使用一些正则表达式来拆分,例如:
String s = String.valueOf(bases);//result = acctacatacctacat
System.out.println(Arrays.toString(s.split("(?<=\\G.{5})")));

如果你想把它放在一行中:

String[] spl = String.valueOf(bases).split("(?<=\\G.{5})");

输出

[accta, catac, ctaca, t]

2

可以利用substring()函数使它更简单。(先将char[]转换为字符串)

 int ls = 5; 
 for (int i = ls; i < bases.length; i+=ls)
     someList.append(bases.substring((i-ls, i)));

注意:如果bases.length%ls!= 0,这将不起作用。 - Andy Turner
我相信它仍然可以工作,只是无法获取字符串末尾的剩余字符——因为问题中没有指定如何处理这些字符——但他的示例只是删除了结尾字符。 - Easton Bornemeier
如果ls == 5bases.length <= 4,使用i == ls作为substring的第二个参数将会失败。 - Andy Turner
如果设置了这些条件,for循环将不会进入其第一次迭代,因为5 < 4将返回false。 - Easton Bornemeier
啊,好的。所以你没有得到异常,只是错过了最后一个子字符串 :) - Andy Turner
是的先生,这就是他的例子中发生的事情,所以我就跟着做了 :) 总是乐于争论逻辑 - 没问题! - Easton Bornemeier

2
你在循环中构建字符串时,应该尽量避免使用字符串连接。
使用StringBuilder:
StringBuilder sb = new StringBuilder(bases.length + (4 + bases.length) / 5);
for (int i = 0; i < bases.length; i += 5) {
  sb.append(bases, i, Math.min(5, bases.length - i));
  sb.append("\n");
}
String str = sb.toString();

1
@YCF_L 啊,第三个参数是长度而不是结束索引。谢谢。(令人困惑的是,在append(CharSequence, int, int)中,第三个参数是结束索引而不是长度)。 - Andy Turner

0

由于在这种情况下,您非常清楚需要组合的序列,因此创建相应的char[]的自定义代码可能是最有效的:

   final int ls = 5;
   final char[] result = new char[bases.length + (bases.length + ls - 1) / ls]
   int nextIndex = 0;
   for (int i = 0; i < bases.length; i += ls) {
      final int size = bases.length - i >= ls ? ls : bases.length - i;
      System.arraycopy(bases, i, result, nextIndex, size);
      nextIndex += size;
      result[nextIndex++] = '\n'; 
   }
   final String resultAsString = new String(result);

1
请注意,这会在bases[0]之后插入第一个换行符,而不是在bases[ls-1]之后插入。 - Andy Turner
@AndyTurner 哎呀!你是对的,谢谢。 - Valentin Ruano
我已经修改了代码,使用了一种自定义解决方案,可能比StringBuilder更高效。 - Valentin Ruano

0

这可能是另一个解决您问题的方案,即使用java8 Stream功能:(为了理解起见,我将逐步介绍答案,但很多内容可以稍后压缩和简化/收集)

int charsPerChunk = 5;
char[] myCharArray = { 'H', 'e', 'l', 'l', 'o', '+', 'X', 'o', 'c', 'e', '!' };
// turn the char array into a Stream of Characters
Stream<Character> myStreamOfCharacters = IntStream.range(0, myCharArray.length).mapToObj(i -> myCharArray[i]);
// collect that into a list of characters
List<Character> myListOfCharacters = myStreamOfCharacters.collect(Collectors.toList());

int size = myListOfCharacters.size();
int fullChunks = (size - 1) / charsPerChunk;
// get a stream of list of characters
Stream<List<Character>> result = IntStream
          .range(0, fullChunks + 1)
          .mapToObj( x -> myListOfCharacters.subList(x * charsPerChunk, x == fullChunks ? size : (x + 1) * charsPerChunk));

// print it
result.forEach(System.out::println);

我认为在这种情况下使用流是过度的。 - Valentin Ruano
同意,尤其是这部分...我的字符流 - ΦXocę 웃 Пepeúpa ツ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接