How to split the string "Thequickbrownfoxjumps" to substrings of equal size in Java.
Eg. "Thequickbrownfoxjumps" of 4 equal size should give the output.
["Theq","uick","brow","nfox","jump","s"]
Similar Question:
How to split the string "Thequickbrownfoxjumps" to substrings of equal size in Java.
Eg. "Thequickbrownfoxjumps" of 4 equal size should give the output.
["Theq","uick","brow","nfox","jump","s"]
Similar Question:
Here's a one-liner version which uses Java 8 IntStream to determine the indexes of the slice beginnings:
String x = "Thequickbrownfoxjumps";
String[] result = IntStream
.iterate(0, i -> i + 4)
.limit((int) Math.ceil(x.length() / 4.0))
.mapToObj(i ->
x.substring(i, Math.min(i + 4, x.length())
)
.toArray(String[]::new);
A StringBuilder version:
public static List<String> getChunks(String s, int chunkSize)
{
List<String> chunks = new ArrayList<>();
StringBuilder sb = new StringBuilder(s);
while(!(sb.length() ==0))
{
chunks.add(sb.substring(0, chunkSize));
sb.delete(0, chunkSize);
}
return chunks;
}
i use the following java 8 solution:
public static List<String> splitString(final String string, final int chunkSize) {
final int numberOfChunks = (string.length() + chunkSize - 1) / chunkSize;
return IntStream.range(0, numberOfChunks)
.mapToObj(index -> string.substring(index * chunkSize, Math.min((index + 1) * chunkSize, string.length())))
.collect(toList());
}
Here is a one liner implementation using Java8 streams:
String input = "Thequickbrownfoxjumps";
final AtomicInteger atomicInteger = new AtomicInteger(0);
Collection<String> result = input.chars()
.mapToObj(c -> String.valueOf((char)c) )
.collect(Collectors.groupingBy(c -> atomicInteger.getAndIncrement() / 4
,Collectors.joining()))
.values();
It gives the following output:
[Theq, uick, brow, nfox, jump, s]
Java 8 solution (like this but a bit simpler):
public static List<String> partition(String string, int partSize) {
List<String> parts = IntStream.range(0, string.length() / partSize)
.mapToObj(i -> string.substring(i * partSize, (i + 1) * partSize))
.collect(toList());
if ((string.length() % partSize) != 0)
parts.add(string.substring(string.length() / partSize * partSize));
return parts;
}
Here is a solution:
To work with all Unicode characters, avoid the obsolete char type. And avoid char-based utilities. Instead, use code point integer numbers.
Call String#codePoints to get an IntStream object, a stream of int values. In the code below, we collect those int values into an array. Then we loop the array, for each integer we append the character assigned to that number to our StringBuilder object. Every nth character, we add a string to our master list, and empty the StringBuilder.
String input = "Thequickbrownfoxjumps";
int chunkSize = 4 ;
int[] codePoints = input.codePoints().toArray(); // `String#codePoints` returns an `IntStream`. Collect the elements of that stream into an array.
int initialCapacity = ( ( codePoints.length / chunkSize ) + 1 );
List < String > strings = new ArrayList <>( initialCapacity );
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < codePoints.length ; i++ )
{
sb.appendCodePoint( codePoints[ i ] );
if ( 0 == ( ( i + 1 ) % chunkSize ) ) // Every nth code point.
{
strings.add( sb.toString() ); // Remember this iteration's value.
sb.setLength( 0 ); // Clear the contents of the `StringBuilder` object.
}
}
if ( sb.length() > 0 ) // If partial string leftover, save it too. Or not… just delete this `if` block.
{
strings.add( sb.toString() ); // Remember last iteration's value.
}
System.out.println( "strings = " + strings );
strings = [Theq, uick, brow, nfox, jump, s]
This works with non-Latin characters. Here we replace q with FACE WITH MEDICAL MASK.
String text = "Theuickbrownfoxjumps"
strings = [The, uick, brow, nfox, jump, s]
Here is my version based on RegEx and Java 8 streams. It's worth to mention that Matcher.results() method is available since Java 9.
Test included.
public static List<String> splitString(String input, int splitSize) {
Matcher matcher = Pattern.compile("(?:(.{" + splitSize + "}))+?").matcher(input);
return matcher.results().map(MatchResult::group).collect(Collectors.toList());
}
@Test
public void shouldSplitStringToEqualLengthParts() {
String anyValidString = "Split me equally!";
String[] expectedTokens2 = {"Sp", "li", "t ", "me", " e", "qu", "al", "ly"};
String[] expectedTokens3 = {"Spl", "it ", "me ", "equ", "all"};
Assert.assertArrayEquals(expectedTokens2, splitString(anyValidString, 2).toArray());
Assert.assertArrayEquals(expectedTokens3, splitString(anyValidString, 3).toArray());
}
The simplest solution is:
/**
* Slices string by passed - in slice length.
* If passed - in string is null or slice length less then 0 throws IllegalArgumentException.
* @param toSlice string to slice
* @param sliceLength slice length
* @return List of slices
*/
public static List<String> stringSlicer(String toSlice, int sliceLength) {
if (toSlice == null) {
throw new IllegalArgumentException("Passed - in string is null");
}
if (sliceLength < 0) {
throw new IllegalArgumentException("Slice length can not be less then 0");
}
if (toSlice.isEmpty() || toSlice.length() <= sliceLength) {
return List.of(toSlice);
}
return Arrays.stream(toSlice.split(String.format("(?s)(?<=\\G.{%d})", sliceLength))).collect(Collectors.toList());
}
public static String[] split(String input, int length) throws IllegalArgumentException {
if(length == 0 || input == null)
return new String[0];
int lengthD = length * 2;
int size = input.length();
if(size == 0)
return new String[0];
int rep = (int) Math.ceil(size * 1d / length);
ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_16LE));
String[] out = new String[rep];
byte[] buf = new byte[lengthD];
int d = 0;
for (int i = 0; i < rep; i++) {
try {
d = stream.read(buf);
} catch (IOException e) {
e.printStackTrace();
}
if(d != lengthD)
{
out[i] = new String(buf,0,d, StandardCharsets.UTF_16LE);
continue;
}
out[i] = new String(buf, StandardCharsets.UTF_16LE);
}
return out;
}
public static List<String> getSplittedString(String stringtoSplit,
int length) {
List<String> returnStringList = new ArrayList<String>(
(stringtoSplit.length() + length - 1) / length);
for (int start = 0; start < stringtoSplit.length(); start += length) {
returnStringList.add(stringtoSplit.substring(start,
Math.min(stringtoSplit.length(), start + length)));
}
return returnStringList;
}