Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split and Loop in java 8

Tags:

java

split

java-8

I have this problem which I want to solve in java 8,

I have a string which is concatenated by .

A.B.C.D

Number of characters in the string can vary.

I have this method, which takes the string as input and number of level deep it has to go, I have to loop through the number that i get after applying a split on string with "." and go just given level deep

private String getResponse (String str, int level) {
// for now, simply print the entire string first and then start removing last alphabet of it one by one till the value of level
// ex : str = A.B.C.D
// System.out.println("Doing a call with key as = " + str); => should give me A.B.C.D
// Apply logic of split 
// System.out.println("Doing a call with key as = " + str); => should give me A.B.C
// Split again
// System.out.println("Doing a call with key as = " + str); => should give me A.B
// this should go in loop till we reach the level
}

Can this be done in java 8?

like image 301
User0911 Avatar asked Jun 03 '15 03:06

User0911


3 Answers

Here's Java-8 solution:

static void getResponse(String input, int level) {
    Stream.iterate(input, str -> {
        int pos = str.lastIndexOf('.');
        return pos == -1 ? "" : str.substring(0, pos);
    }).limit(level+1).forEach(System.out::println);
}

If you know for sure that level does not exceed the number of dots, you can omit the check:

static void getResponseUnsafe(String input, int level) {
    Stream.iterate(input, str -> str.substring(0, str.lastIndexOf('.')))
            .limit(level + 1).forEach(System.out::println);
}
like image 117
Tagir Valeev Avatar answered Oct 11 '22 15:10

Tagir Valeev


No looping is necessary, since string can be split into an array in a single String.split call. (Note that String.split takes a regex.) To handle the "level", just subtract it from the length of the array of splits. Instead of copying the array subrange, convert it into a List and use subList():

String getResponse(String str, int level) {
    String[] splits = str.split("\\.");
    if (level < 0 || level > splits.length) {
        throw new IllegalArgumentException();
    }
    return String.join(".", Arrays.asList(splits).subList(0, splits.length - level));
}

The output of

    for (int level = 0; level < 5; level++) {
        System.out.printf("level %d: %s%n", level, getResponse("A.B.C.D", level));
    }

will be

level 0: A.B.C.D
level 1: A.B.C
level 2: A.B
level 3: A
level 4: 

Note that this does require Java 8 because it requires String.join(). (But it doesn't require streams or even lambdas!)

like image 5
Stuart Marks Avatar answered Oct 11 '22 16:10

Stuart Marks


Your comments mention using split(), so here's an example of using split(), Arrays.copyOfRange() (to remove the last letter), and String.Join() to put the result of Arrays.copyOfRange() back together for the next recursive call.

public static void main(String[] args) {
    String string = "A.B.C.D";
    getResponse(string, 3);
    System.out.println();

    getResponse(string, 2);
    System.out.println();

    getResponse(string, 1);
    System.out.println();
}

private static void getResponse(String str, int level) {
    if (level < 0 || str.isEmpty())
        return;

    System.out.println(str);

    String[] strPieces = str.split("\\.");
    if (strPieces.length > level) {
        getResponse(String.join(".", Arrays.copyOfRange(strPieces, 0, strPieces.length - 1)), level - 1);
    }
}

Results:

A.B.C.D
A.B.C
A.B
A

A.B.C.D
A.B.C
A.B

A.B.C.D
A.B.C
like image 2
Shar1er80 Avatar answered Oct 11 '22 14:10

Shar1er80