-1

I'm using hashmap in Java to hold three pairs of servers in format (name,size), and then pass this hashmap to Javascript.

In Javascript there is no comma after the last entry:

data: [
{
   name : "client3",
   y:23,
},
{
   name : "client1",
   y:245,
},
{
   name : "client2",
   y:23,
}]

so I don't know how to get rid of this comma in Java using HashMap iterator :

for (Map.Entry<String, String> entry : listClientSize.entrySet()) {
    String name = entry.getKey().toString();;
    String size = entry.getValue();
    out.println("name : \""+name+"\",");
    out.println("y:"+size+",");
    out.println("},");
}

Any ideas?

johnny 5
  • 19,893
  • 50
  • 121
  • 195
hawarden_
  • 1,904
  • 5
  • 28
  • 48

6 Answers6

2

Instead of writing the comma at the end of the loop, write it at the beginning. It's much easier to check first iteration than last iteration.

boolean first = true;
for (Map.Entry<String, String> entry : listClientSize.entrySet()) {
    String name = entry.getKey().toString();;
    String size = entry.getValue();
    if (first)
        first = false;
    else
        out.println("},");
    out.println("{");
    out.println("name : \""+name+"\",");
    out.println("y:"+size);
}
out.println("}");

BTW: You were missing the print of the start-brace {, and had a comma after the y value.

Update: Since that pattern for handling first iteration is so common, and the action is so simple (usually just appending a separator), I usually collapse the code as follows (don't do this if you have strict coding standards):

if (first) first = false; else out.println("},");
Andreas
  • 154,647
  • 11
  • 152
  • 247
2

It seems you are creating JSON, so consider using proper JSON parser to generate your results. For instance with gson library your code could look like

Class containing single informations you want to store

public class Server{
    private String name;
    private int value;
    public Server(String name, int value) {
        this.name = name;
        this.value = value;
    }
    //getters and setters
}

You can use this class like:

List<Server> list = new ArrayList<>();
list.add(new Server("1", 245));
list.add(new Server("2", 23));
list.add(new Server("3", 23));

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(list);
System.out.println(json);

which will generate:

[
  {
    "name": "1",
    "value": 245
  },
  {
    "name": "2",
    "value": 23
  },
  {
    "name": "3",
    "value": 23
  }
]

You can add later data = at start if you absolutely need it.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • +1 for suggesting valid alternative, although that *may* not be an appropriate solution for OP, depending on context/restrictions. – Andreas Aug 27 '15 at 15:54
  • 1
    @Andreas True, if OP is doing homework assignment then (s)he may not be allowed to use external libraries. But I will leave this solution as alternative one so others could also learn how to solve this task easily :) – Pshemo Aug 27 '15 at 15:56
  • @Thanks but I'm not generating JSON, this is to print a pie chart using highchart.js – hawarden_ Aug 28 '15 at 07:43
  • 1
    @brest1007 That is strange because JSON is JavaScript Object Notation, so you probably should be able to use object generated by this answer in `highchart.js`. Have you tried it? – Pshemo Aug 28 '15 at 12:12
2

If you can use Java 8, use StringJoiner

    final StringJoiner stringJoiner = new StringJoiner(",");

    Map<String,String> listClientSize = new HashMap<String,String>(){{
        put("client3","23");
        put("client1","245");
        put("client2","23");
    }};
    for (Map.Entry<String, String> entry : listClientSize.entrySet()) {
        String name = entry.getKey().toString();;
        String size = entry.getValue();
        stringJoiner.add(String.format("{name:\"%s\", y:%s}", name, size));
    }
    System.out.println(stringJoiner.toString());
Mike Hogan
  • 9,933
  • 9
  • 41
  • 71
  • You can also add prefix `data: [` and suffix `]` like `new StringJoiner(",", "data: [", "]");`. – Pshemo Aug 27 '15 at 16:06
1

To get rid of the comma after the y property, which is the last property in the object, just do this:

for (Map.Entry<String, String> entry : listClientSize.entrySet()) {
        String name = entry.getKey().toString();;
        String size = entry.getValue();
        out.println("name : \""+name+"\",");
        out.println("y:"+size);
        out.println("},");
    }

To get rid of the comma at the very end, instead of printing from the for loop, build up a string and then use substring to cut off the last character after your for loop, then print the string

Jacob Petersen
  • 1,463
  • 1
  • 9
  • 17
1

One easy thing you could try is accumulating the string to print in a StringBuilder, and then stripping the last comma, using substring. It should look like this:

StringBuilder output = new StringBuilder();
for (Map.Entry<String, String> entry : listClientSize.entrySet()) {
        String name = entry.getKey();
        String size = entry.getValue();
        output.append("{name :\"").append(name).append("\", ");
        output.append("y: ").append(size).append("},");     
}
String toPrint = output.substring(1, output.size() - 1);
out.println(toPrint);
Danail Alexiev
  • 7,624
  • 3
  • 20
  • 28
  • Kudos for use of `StringBuilder`, but you can improve code by chaining `append` as in `output.append("{name :\"").append(name).append(", ")`. --- **Note:** You're missing an end-quote for the name value. – Andreas Aug 27 '15 at 15:52
  • True that, thanks for the tips. I am not the biggest fan of method chaining, but in this case it may be justified. – Danail Alexiev Aug 27 '15 at 16:34
  • Why are you declaring and initializing `name` and `size` outside the loop? It was better inside the loop, to keep them locally scoped. – Andreas Aug 27 '15 at 16:39
  • I don't like creating references in a loop, old habits I guess. – Danail Alexiev Aug 27 '15 at 16:46
  • It doesn't change the generated bytecode, except for the unnecessary initializer, but it opens the scope of the variables, and a reader of the code would have to check the rest of the method (which *could* be much longer) to see if `name` or `size` is used later. Defining them inside explicitly declares "used here and nowhere else". – Andreas Aug 27 '15 at 16:50
  • Yope, I am aware of this, but I was doing it like this for a long time and I am still in the process of changing my habit. – Danail Alexiev Aug 27 '15 at 16:59
  • Happy to help teach an old dog *(dang, I'm one of those)* new tricks. ;-) – Andreas Aug 27 '15 at 17:02
  • I am happy to see people actually helping others, and not just downvoting without explanation. – Danail Alexiev Aug 27 '15 at 20:26
0

You probably need a way to tell if its not last entry then append the comma. One simplistic way is to keep a counter n n increment each iteration. If counter != hashmap size append comma