简体   繁体   中英

Java: How to split a string with delimiter by limiting the number of characters in a string?

I have a scenario where I have to split a string (which has comma separated values) limiting the maximum number of characters in a string while maintaining the comma separated format.

For eg., String str = "test,et,ste,ts,tst,est,ste,tstete,sts,tet,estst,tet"

Say the maximum number of characters in a string can be 10. Then my output should be:

test,et (7 chars)
ste,ts,tst (10 chars)
est,ste (7 chars)
tstete,sts (10 chars)
tet,estst (9 chars)
tet (3 chars)

Basically the output is going to be looped and appended to a IN clause in the query but the IN clause could handle only (maximum no of chars) so splitting the string (with meaning full comma separated values) in case if the length of the string exceeds the limit.

You can do something like this(look at the comments for explanation):

public static void main(String[] args) {
    String str = "test,et,ste,ts,tst,est,ste,tstete,sts,tet,estst,tet";

    // Split it first
    String words[] = str.split(",");

    // Use a buffer
    StringBuffer sb = new StringBuffer("");

    List<String> result = new ArrayList<>();

    String delim = "";

    // Iterate through the words. 
    for(int i = 0; i< words.length; i++) {
        // You will add the comma so total length should be less 
        // than 10.
        if(sb.length() + words[i].length() < 10) {
            sb.append(delim);
            sb.append(words[i]);
            delim = ",";
        }
        else {
            delim = "";
            result.add(sb.toString());
            System.out.println(sb.toString());
            sb = new StringBuffer(words[i]);
            delim = ",";
        }
    }

    // Print to check the results
    for(String s: result) {
        System.out.println(s);
    }
}

this task is a tricky one — the following lambda expression solves it

comma = false; // class boolean variable
last = 0;      // class int variable

Stream.of( str.split( "," ) ).collect(
  Collector.of( () -> new StringBuilder(),
    (buf, s) -> {
      if( buf.length() - last + s.length() < 10 ) {
        buf.append( comma ? "," : "" ).append( s );
        comma = true;
      }
      else {
        int len = buf.length();
        buf.append( " (" ).append( len - last ).append( " chars)\n" );
        last = buf.length();
        buf.append( s );
      }
    },
    (buf1, buf2) -> null,  // unused
    buf -> {
      int len = buf.length();
      return( buf.append( " (" ).append( len - last ).append( " chars)\n" ).toString() );
    } ) );

and without the (… chars)-explanation:

Stream.of( str.split( "," ) ).collect(
  Collector.of( () -> new StringBuilder(),
    (buf, s) -> {
      if( buf.length() - last + s.length() < 10 ) {
        buf.append( comma ? "," : "" ).append( s );
        comma = true;
      }
      else {
        buf.append( '\n' );
        last = buf.length();
        buf.append( s );
      }
    },
    (buf1, buf2) -> null,  // unused
    buf -> {
      return( buf.append( '\n' ).toString() );
    } ) );

the required output is returned as string…

I would do this:

  1. split the input string by comma. You get an array back with the single strings, eg arr[]
  2. initialize a temporary string variable to store the outputs, eg out = ""
  3. loop over the array, eg for(int i = 0; i< arr.length; i++)
  4. within the loop: if the length of out combined with the length of the current array entry is smaller to 10, then add the current array entry to out, else print out out, reset out and go on, eg if (out.length + arr[i].length < 10) {out += ","+arr[i];} else {print out; out = "";} if (out.length + arr[i].length < 10) {out += ","+arr[i];} else {print out; out = "";}

Maybe I forgot something... but you should get the idea, right?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM