# Echo implemented in Java

I implemented a simple version of echo(1) command utility. The program works as described in the man page: it writes to the standard output all command line arguments, separated by a whitespace and end with a newline. It can process the option -n that avoid to print the newline.

About my implementation, it is not complete, because it doesn't interpret common backslash-escaped characters (for example \n, \c, and so forth). i used a StringBuilder object to build the output string, because I'm not sure that the standard output is buffered. I also make some checks so the program can work without specifying any arguments.

You can compile the program with javac JEcho and run it with java JEcho <...>.

JEcho.java

/**
* JEcho writes any command line argument to the standard output; each argument
* is separated by a single whitespace and end with a newline (you can
* specify '-n' to suppress the newline).
*
* This program doesn't interpret common backslash-escaped characters (for
* exampe '\n' or '\c').
*/
public class JEcho {
public static void main(String[] args) {
boolean printNewline = true;
int posArgs = 0;

if (args.length > 0 && args[0].equals("-n")) {
printNewline = false;
posArgs = 1;
}

StringBuilder outputBuilder = new StringBuilder();

for (; posArgs < args.length; posArgs++) {
outputBuilder.append(args[posArgs]);
outputBuilder.append(" "); // Separator.
}

// Remove the trailing whitespace at the end.
int outputLength = outputBuilder.length();
if (outputLength > 0)
outputBuilder.deleteCharAt(outputBuilder.length() - 1);

String output = outputBuilder.toString();

if (printNewline)
System.out.println(output);
else
System.out.print(output);
}
}

• can you explain a bit more about the purpose of JEcho? is it akademical or du you want to proof something? do you want to write n utility for your home computer? – Martin Frank Feb 15 '18 at 13:27
• why don't you print the arguments directly? – Martin Frank Feb 15 '18 at 13:32
• @MartinFrank I'm learning Java, so I'm reimplementing some utilities that I use frequently. This program is not production ready, it is only an exercise. – user146184 Feb 15 '18 at 13:33
• @MartinFrank because I need to separate all arguments with a whitespace and because I don't know if the standard output is buffered. – user146184 Feb 15 '18 at 13:34
• A standard POSIX echo doesn't interpolate any backslash escapes either, so this is a faithful implementation. – Toby Speight Feb 15 '18 at 16:25

If you're using Java 8, you can use StringJoiner.

/**
* JEcho writes any command line argument to the standard output; each argument
* is separated by a single whitespace and end with a newline (you can
* specify '-n' to suppress the newline).
*
* This program doesn't interpret common backslash-escaped characters (for
* exampe '\n' or '\c').
*/
public class JEcho {
public static void main(String[] args) {
boolean printNewline = true;
int posArgs = 0;

if (args.length > 0 && args[0].equals("-n")) {
printNewline = false;
posArgs = 1;
}

StringJoiner outputBuilder = new StringJoiner(" ");

for (; posArgs < args.length; posArgs++) {
}

String output = outputBuilder.toString();

if (printNewline)
System.out.println(output);
else
System.out.print(output);
}
}

• What are the differences between StringBuilder and StringJoiner? – user146184 Feb 15 '18 at 13:27
• @ema-pe I accidentally forgot the " " argument. StringJoiner adds something between the values. – Solomon Ucko Feb 15 '18 at 13:55
• Doesn't Java have a foreach, or doesn't have something similar to C# String.Join( separator, value ) where separator would be the " " and value the args? EDIT: I've seen that Java as a similar method, so why don't use it? – auhmaan Feb 15 '18 at 18:28
• @auhmaan, the -n argument complicates things. – Solomon Ucko Feb 15 '18 at 21:13

as a matter of an excersice i would advise you to keep your parameters as List<String>...

public static void main(String[] args) {
boolean printNewline = true;
List<String> parameters = new ArrayList<>(Arrays.asList(args);
if (args.length > 0 && isNewLine(args[0]) ) {
printNewline = false;
parameters.remove(0); //remove the first one
}

String output = parameters.stream()
.collect(Collectors.joining(" ", "", printNewLine ? System.lineSeparator() : "")

System.out.print(output);
}


NOTE: the method isNewLine() is not shown here - but you should consider using such a method to prevent a missing argument... think of -n, -N, /n, /N, all these parameters can be handle in the isNewLine-method...

• I would push the ternary op as deep as possible: parameters.stream().collect(Collectors.joining(printNewLine ?"\n":",")) – Landei Feb 15 '18 at 13:49
• man - formatting in stackjoverflow always tears me down =) haha – Martin Frank Feb 15 '18 at 13:49
• very nice @Landei - would you please edit my post! – Martin Frank Feb 15 '18 at 13:50
• This doesn't do the same as the question. Namely, printNewLine should print a line after the rest of the string, not as word separator. Then, the separator is always a whitespace, not ",". Fixing these is rather easy actually: Collectors.joining(" ", "", printNewLine ? System.lineSeparator() : "") and using System.out.print instead of System.out.println. – Olivier Grégoire Feb 15 '18 at 16:08
• i have added your valuable input @OlivierGrégoire thank you so much for precising this requirement! - even though you tried to edit my post it was disapproved... very bad, considering the comments where i especially asked you to do so - anyway, keep up the good work & thanks again! – Martin Frank Feb 16 '18 at 11:01