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?
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);
}
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!)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With