3

I need to convert an array of char into several lines of a certain size. For example, considering this array :

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

the expected output would be for a size of 5:

accta
catac
ctaca

I'm currently using this code :

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

Is there some built-in function to achieve this in java 8? Is there a better way to solve this ?

felix
  • 9,007
  • 7
  • 41
  • 62

5 Answers5

5

You can convert the char[] to string then you can use split with some regex like :

String s = String.valueOf(bases);//result = acctacatacctacat
System.out.println(Arrays.toString(s.split("(?<=\\G.{5})")));

If you want to make it in one line :

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

output

[accta, catac, ctaca, t]
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
2

Could probably utilize substring() to make it simpler. (Convert the char[] to string first)

 int ls = 5; 
 for (int i = ls; i < bases.length; i+=ls)
     someList.append(bases.substring((i-ls, i)));
Easton Bornemeier
  • 1,918
  • 8
  • 22
2

You should pretty much never use string concatenation in a loop to build a string.

Use a 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();
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 1
    @YCF_L ah, that third parameter is a length, not the end index. Thanks. (Confusingly, the third parameter in `append(CharSequence, int, int)` is an end index, not a length). – Andy Turner Jun 22 '17 at 18:48
0

Since in this case you have a very clear idea of the sequence you need to compose perhaps a custom code to create the corresponding char[] would be the most efficient:

   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);
Valentin Ruano
  • 2,726
  • 19
  • 29
0

This can be another solution to your question that is using the java8 Stream power: (for the sake of the comprehension I will leave the answer step by step, but a lot can be condensed and simplified/collected later )

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);
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97