How do I append a newline character for all lines except the last one?

I’m iterating through a HashMap (see my earlier question for more detail) and building a string consisting of the data contained in the Map. For each item, I will have a new line, but for the very last item, I don’t want the new line. How can I achieve this? I was thinking I could so some kind of check to see if the entry is the last one or not, but I’m not sure how to actually do that.

Thanks!

In vim, how can I delete all lines in a file except the last 100 lines?

In vim when my cursor is on the first line I can press: 100dd to delete the first 100 lines. But how do I delete all lines except the last 100 lines?

PHP script to remove all lines of the file except last n lines

How can I remove all the lines except the last n lines of the text file? What code should I use to remove other lines except for last two lines ? I have one script which does opposite as this one : $

one-liner: print all lines except the last 3?

I would like to simulate GNU’s head -n -3, which prints all lines except the last 3, because head on FreeBSD doesn’t have this feature. So I am thinking of something like seq 1 10 | perl -ne … Here

Bash: remove all lines of input except last n lines

i want to remove all lines except n last or first n lines with a short one-liner eg.: — aaaa bbbb cccc dddd cat/echo/find … | sed < all except last 2 lines > should result aaaa bbbb — aaa

How to remove all lines except .c extention(at last) lines using perl scripting

I’ve a string $string which has got list of lines, some ending with *.c, *.pdf,etc and few without any extensions(these are directories). I need to remove all lines except *.c lines. How can i do that

How do I prevent the last newline?

<textarea style=resize: none;> <?php while ($row = mysql_fetch_array($result)) { echo $row[1] . /n; } ?> </textarea> I want to prevent the last value from having a newline – how

jQuery appendTo all elements except last one

I am trying to append all elements of the same class td.top except last one to another place, but I can’t figure out how is this possible.. Any ideas are welcomed, I am kind of stuck.. Thank you for

How to append a newline to StringBuilder

I have a StringBuilder object, StringBuilder result = new StringBuilder(); result.append(someChar); Now I want to append a newline character to the StringBuilder. How can I do it? result.append(/n)

How do I have a border-bottom on all except the last item

If i have a ul, how do i set a border-bottom on all the li items except the last one? I’m also trying to make the width of the border 180px. here’s my code: HTML <ul class=sideNav> <li>&

How do I remove all class divs except the last 2 using jquery?

How do I remove all class divs except the last 2 using jquery? I have a set of comments that show in a .comment_container class. When show all comments is clicked a list of all comments for a particul

Answers

Change your thought process from “append a line break all but the last time” to “prepend a line break all but the first time”:

boolean first = true;
StringBuilder builder = new StringBuilder();

for (Map.Entry<MyClass.Key,String> entry : data.entrySet()) {
    if (first) {
        first = false;
    } else {
        builder.append("/n"); // Or whatever break you want
    }
    builder.append(entry.key())
           .append(": ")
           .append(entry.value());
}

Assuming your foreach loop goes through the file in order just add a new line to every string and remove the last new line when your loop exits.

Not sure if this is the best, but it´s the easier way to do:

loop through all the values and append the /n normally in the stringbuffer. Then, do something like this

sb.setLength(sb.length()-1);

one method (with apologies to Jon Skeet for borrowing part of his Java code):

StringBuilder result = new StringBuilder();

string newline = "";  
for (Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    result.append(newline)
       .append(entry.key())
       .append(": ")
       .append(entry.value());

    newline = "/n";
}

Ususally for these kind of things I use apache-commons-lang StringUtils#join. While it’s not really hard to write all these kinds of utility functionality, it’s always better to reuse existing proven libraries. Apache-commons is full of useful stuff like that!

If you use iterator instead of for…each your code could look like this:

StringBuilder builder = new StringBuilder();

Iterator<Map.Entry<MyClass.Key, String>> it = data.entrySet().iterator();

while (it.hasNext()) {
    Map.Entry<MyClass.Key, String> entry = it.next();

    builder.append(entry.key())
    .append(": ")
    .append(entry.value());

    if (it.hasNext()) {
        builder.append("/n");
    }
}

Here’s my succinct version, which uses the StringBuilder’s length property instead of an extra variable:

StringBuilder builder = new StringBuilder();

for (Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    builder.append(builder.length() > 0 ? "/n" : "")
           .append(entry.key())
           .append(": ")
           .append(entry.value());
}

(Apologies and thanks to both Jon and Joel for “borrowing” from their examples.)

What about this?

StringBuilder result = new StringBuilder();

for(Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    builder.append(entry.key())
       .append(": ")
       .append(entry.value())
       .append("/n");
}

return builder.substring(0, builder.length()-1);

Obligatory apologies and thanks to both Jon and Joel for “borrowing” from their examples.

This is where a join method, to complement split, would come in handy, because then you could just join all the elements using a new line as the separator, and of course it doesn’t append a new line to the end of the result; that’s how I do it in various scripting languages (Javascript, PHP, etc.).

If you use Class Separator, you can do

StringBuilder buf = new StringBuilder();
Separator separator = new Separator("/n");
for (Map.Entry<MyClass.Key,String> entry: data.entrySet()) {
    builder.append(separator)
       .append(entry.key())
       .append(": ")
       .append(entry.value());
}

The separator prints in empty string upon its first use, and the separator upon all subsequent uses.

Ha! Thanks to this post I’ve found another way to do this:

public static class Extensions
{
    public static string JoinWith(this IEnumerable<string> strings, string separator)
    {
        return String.Join(separator, strings.ToArray());
    }
}

Of course this is in C# now and Java won’t (yet) support the extension method, but you ought to be able to adapt it as needed — the main thing is the use of String.Join anyway, and I’m sure java has some analog for that.

Also note that this means doing an extra iteration of the strings, because you must first create the array and then iterate over that to build your string. Also, you will create the array, where with some other methods you might be able to get by with an IEnumerable that only holds one string in memory at a time. But I really like the extra clarity.

Of course, given the Extension method capability you could just abstract any of the other code into an extension method as well.

This is probably a better example…

final StringBuilder buf = new StringBuilder();
final String separator = System.getProperty("line.separator"); // Platform new line
for (Map.Entry<MyClass.Key,String> entry: data.entrySet()) {
    builder.append(entry.key())
       .append(": ")
       .append(entry.value())
       .append(separator);
}
// Remove the last separator and return a string to use.
// N.b. this is likely as efficient as just using builder.toString() 
// which would also copy the buffer, except we have 1 char less 
// (i.e. '/n').
final String toUse = builder.substring(0, builder.length()-separator.length()-1);

One solution is to create a custom wrapper to StringBuilder. It can’t be extended, thus a wrapper is required.

public class CustomStringBuilder {

final String separator = System.getProperty("line.separator");

private StringBuilder builder = new StringBuilder();

public CustomStringBuilder appendLine(String str){
    builder.append(str + separator);
    return this;
}

public CustomStringBuilder append(String str){
    builder.append(str);
    return this;
}

public String toString() {
    return this.builder.toString();
}

}

Implementation like such:

CustomStringBuilder builder = new CustomStringBuilder();

//iterate over as needed, but a wrapper to StringBuilder with new line features.

builder.appendLine("data goes here");
return builder.toString();

This does have some downsides:

  • Writing code that’s typically not “domain / business” centric
  • Not using open source standard solution like: StringUtils.join
  • Forced to maintain a class that wraps a JDK class that’s final and thus updates required long term.

I went with the StringUtils.join solution for iterating over collections and even building lightweight build method patterns in the code.

Let libraries do this for you.

import com.sun.deploy.util.StringUtils;

as well as many others have StringUtils, which has a join method. You can do this in one line:

StringUtils.join(list, DELIMITER);

But for more context, here is how you could do it with a hashmap.

public static String getDelimitatedData(HashMap<String, String> data) {
    final String DELIMITER = "/n"; //Should make this a variable
    ArrayList<String> entries = new ArrayList<>();

    for (Map.Entry<String, String> entry : data.entrySet()) {
        entries.add(entry.getKey() + ": " + entry.getValue());
    }

    return StringUtils.join(entries, DELIMITER);
}