patternjavaMinor
Empty Line delimiter, single line output
Viewed 0 times
lineemptyoutputsingledelimiter
Problem
I'm used to only processing, at most, one line of a file at a time. This is my first time changing the delimiter, and the objective here is to take a file containing lines such as:
and produce single line output:
What I've done works, but it feels like a work-around to some superior alternative I'm sure exists. What do you think?
Bubbles,
Blossom and
Buttercup
Nostalgic
Examples for the
Win.
Quick Brown Fox
Jumping Over Lazy
Dog.
and produce single line output:
Bubbles, Blossom and Buttercup.
Nostalgic Examples for the Win.
Quick Brown Fox Jumping Over Lazy Dog.
What I've done works, but it feels like a work-around to some superior alternative I'm sure exists. What do you think?
import java.io.File;
import java.io.FileNotFoundException;
import java.util.regex.Pattern;
import java.util.Scanner;
public class TestDelim {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File(args[0]))
.useDelimiter(Pattern.compile("^\\s*$", Pattern.MULTILINE));
Scanner output;
StringBuilder sb = new StringBuilder();
while (input.hasNext()) {
output = new Scanner(input.next());
while (output.hasNextLine()) {
sb.append(' ').append(output.nextLine());
}
System.out.println(sb.toString().trim());
sb.setLength(0);
}
}
}
Solution
I don't really see why you used two scanners instead of just one.
And I also don't see the need for a custom delimiter.
You can use a simpler alternative logic:
That is:
An easy way to "test" this is by instantiating a
I don't know a simpler way to do this.
But I have some ideas for possibly interesting variations you could try, for example:
-
Instead of collecting lines in a buffer, print as you go. That will save you memory usage. To track whether to put a space or not, you would need a flag of some sort. (A simple boolean would do.)
-
Instead of printing paragraph by paragraph, let the buffer grow and print at the very end. This uses more memory, but it will make the implementation properly testable, as you could return the buffer, which can be used by unit tests.
Both alternatives have advantages and disadvantages.
The simplified version I gave you above is somewhere in the middle.
And I also don't see the need for a custom delimiter.
You can use a simpler alternative logic:
- Process line by line
- If the line is not empty, append it + a space
- If the line is empty
- Print the content buffer, except the last charater (the extra space)
- Reset the buffer
- At the end, if the buffer is not empty, print its content, except the last character
That is:
StringBuilder sb = new StringBuilder();
while (input.hasNextLine()) {
String line = input.nextLine();
if (!line.isEmpty()) {
sb.append(line).append(' ');
} else {
System.out.println(sb.substring(0, sb.length() - 1));
sb.setLength(0);
}
}
if (sb.length() > 0) {
System.out.println(sb.substring(0, sb.length() - 1));
}An easy way to "test" this is by instantiating a
Scanner with a string containing newlines:Scanner input = new Scanner("Bubbles,\n" +
"Blossom and\n" +
"Buttercup\n" +
"\n" +
"Nostalgic\n" +
"Examples for the\n" +
"Win.\n" +
"\n" +
"Quick Brown Fox\n" +
"Jumping Over Lazy\n" +
"Dog.");I don't know a simpler way to do this.
But I have some ideas for possibly interesting variations you could try, for example:
-
Instead of collecting lines in a buffer, print as you go. That will save you memory usage. To track whether to put a space or not, you would need a flag of some sort. (A simple boolean would do.)
-
Instead of printing paragraph by paragraph, let the buffer grow and print at the very end. This uses more memory, but it will make the implementation properly testable, as you could return the buffer, which can be used by unit tests.
Both alternatives have advantages and disadvantages.
The simplified version I gave you above is somewhere in the middle.
Code Snippets
StringBuilder sb = new StringBuilder();
while (input.hasNextLine()) {
String line = input.nextLine();
if (!line.isEmpty()) {
sb.append(line).append(' ');
} else {
System.out.println(sb.substring(0, sb.length() - 1));
sb.setLength(0);
}
}
if (sb.length() > 0) {
System.out.println(sb.substring(0, sb.length() - 1));
}Scanner input = new Scanner("Bubbles,\n" +
"Blossom and\n" +
"Buttercup\n" +
"\n" +
"Nostalgic\n" +
"Examples for the\n" +
"Win.\n" +
"\n" +
"Quick Brown Fox\n" +
"Jumping Over Lazy\n" +
"Dog.");Context
StackExchange Code Review Q#81852, answer score: 6
Revisions (0)
No revisions yet.