divide a range of numbers into groups of 10, 100, 1000, 10000 and so on Given a start and end of a range as string, for example:

String start = "1230000";
String end   = "1285999";


Generate the shortest list possible with prefixes that include the whole range,
so that for any number from the given range there is a list elemnet which can be used as a prefix. For above example the list would contain:

 123,124,125,126,127,1280,1281,1282,1283,1284,1285


Explanation 

The length of the strings may vary (6 - 12) but start.length() and end.length() are always equal.
The above range can be manually divided into the sub ranges:

    //1230000 - 1239999
    //1240000 - 1249999
    //1250000 - 1259999
    //1260000 - 1269999
    //1270000 - 1279999
    //1280000 - 1289999 this range is not completly included so make the ranges smaller with a factor 10
    //1280000 - 1280999
    //1281000 - 1281999
    //1282000 - 1282999
    //1283000 - 1283999
    //1284000 - 1284999
    //1285000 - 1285999


By storing the common substring of each start and end number of the subranges one can easliy validiate that any given number from the range starts with 123,124,125,126,127,1280,1281,1282,1283,1284 or 1285.

Here is a very naive but working solution to print the prefixes:

public static void main(String[] args) {
    String start = "1230000";
    String end   = "1285999";

    while(start.charAt(start.length()-1) == '0' &amp;&amp; end.charAt(start.length()-1) == '9'){
        start = start.substring(0,start.length()-1);
        end = end.substring(0,end.length()-1);
    }

    long st = Long.parseLong(start);
    long en = Long.parseLong(end);
    for(long i = st; i &lt;= en; ){
         if(i % 1000 == 0 &amp;&amp; i + 999 &lt;= en){
            System.out.println(i/1000); 
            i = i + 1000;
        }
        else if(i % 100 == 0 &amp;&amp; i + 99 &lt;= en){
            System.out.println(i/100); 
            i = i + 100;
        }
        else if(i % 10 == 0 &amp;&amp; i + 9 &lt;= en){
            System.out.println(i/10); 
            i = i + 10;
        }
        else {
            System.out.println(i); 
            i = i + 1;
        }
    }
}


For some not so nice ranges like the above I have to extend my for loop:

public static void main(String[] args) {
    String start = "1279995";
    String end   = "1285999";

    while(start.charAt(start.length()-1) == '0' &amp;&amp; end.charAt(start.length()-1) == '9'){
        start = start.substring(0,start.length()-1);
        end = end.substring(0,end.length()-1);
    }

    long st = Long.parseLong(start);
    long en = Long.parseLong(end);
    for(long i = st; i &lt;= en; ){
        if(i % 1000000 == 0 &amp;&amp; i + 999999 &lt;= en){
            System.out.println(i/1000000); 
            i = i + 1000000;
        }
        else if(i % 100000 == 0 &amp;&amp; i + 99999 &lt;= en){
            System.out.println(i/100000); 
            i = i + 100000;
        }
        else if(i % 10000 == 0 &amp;&amp; i + 9999 &lt;= en){
            System.out.println(i/10000); 
            i = i + 10000;
        }
        else if(i % 1000 == 0 &amp;&amp; i + 999 &lt;= en){
            System.out.println(i/1000); 
            i = i + 1000;
        }
        else if(i % 100 == 0 &amp;&amp; i + 99 &lt;= en){
            System.out.println(i/100); 
            i = i + 100;
        }
        else if(i % 10 == 0 &amp;&amp; i + 9 &lt;= en){
            System.out.println(i/10); 
            i = i + 10;
        }
        else {
            System.out.println(i); 
            i = i + 1;
        }
    }
}


Which I found not very nice. Any ideas how to optimise my approach or do some one have another approach (I am open to everything, Regex, streams, recursion .. )?
Even the “extended version” does not handle the cases where start and end have more than 6 trailing zeros in common. Instead of hard-coding those ranges and a long if/else if/... statement you can determine the largest fitting range dynamically in a loop:

for (long i = st; i &lt;= en; ) {
    // Determine `range` as largest power of 10 with `i % range == 0`
    // and `i + range - 1 &lt;= en`:
    int range = 1;
    while (range &lt;= i &amp;&amp; i % range == 0 &amp;&amp; i + range - 1 &lt;= en) {
        range *= 10;
    }
    range /= 10;

    System.out.println(i / range); 
    i += range;
}


Removing common zeros/nines is more efficiently done in integer arithmetic instead of string manipulation:

while (st % 10 == 0 &amp;&amp; en % 10 == 9) {
    st /= 10;
    en /= 10;
}


I would move the computation from main() into a separate function and separate it from the I/O. That increases the clarity of the program and allows to add test cases more easily. In a comment you said that you need the result as List&lt;String&gt;:

public static List&lt;String&gt; computePrefixes(long start, long end) {
    List&lt;String&gt; prefixes = new ArrayList&lt;String&gt;();

    while (start % 10 == 0 &amp;&amp; end % 10 == 9) {
        start /= 10;
        end /= 10;
    }

    for (long i = start; i &lt;= end; ) {
        // Determine `range` as largest power of 10 with `i % range == 0`
        // and `i + range - 1 &lt;= en`:
        int range = 1;
        while (range &lt;= i &amp;&amp; i % range == 0 &amp;&amp; i + range - 1 &lt;= end) {
            range *= 10;
        }
        range /= 10;

        prefixes.add(String.valueOf(i / range));
        i += range;
    }

    return prefixes;
}

public static void main(String[] args) {
    String start = "1230000";
    String end   = "1285999";

    long st = Long.parseLong(start);
    long en = Long.parseLong(end);
    List&lt;String&gt; prefixes = computePrefixes(st, en);
    System.out.println(prefixes);
}


You may also want to check the validity of the parameters (1 &lt;= start &lt;= end).

Finally note that there is still a problem with numbers close to Long.MAX_VALUE because the calculations can overflow. If that is an issue then the range calculations and comparisons have to be done more carefully:

public static List&lt;String&gt; computePrefixes(long start, long end) {
    List&lt;String&gt; prefixes = new ArrayList&lt;String&gt;();

    while (start % 10 == 0 &amp;&amp; end % 10 == 9) {
        start /= 10;
        end /= 10;
    }

    for (long i = start; ; ) {
        // Determine `range` as largest power of 10 with `i % range == 0`
        // and `i + range - 1 &lt;= end`:
        int range = 1;
        while (range &lt;= Long.MAX_VALUE / 10 &amp;&amp; range &lt;= i &amp;&amp; i % range == 0 &amp;&amp; range - 1 &lt;= end - i) {
            range *= 10;
        }
        range /= 10;

        prefixes.add(String.valueOf(i / range));
        if (i == end) {
            break;
        }
        i += range;
    }

    return prefixes;
}