3

I have a collection of Ingredient objects for which I'd like get all their names (via getName()) and join them into a comma-delimited string. Currently my code looks like this:

public static String getIngredientList(Collection<Ingredient> ingredients) {
    final Iterator<Ingredient> iterator = ingredients.iterator();
    final String[] names = new String[ingredients.size()];

    for (int i = 0; iterator.hasNext(); i++) {
        names[i] = iterator.next().getName();
    }

    return TextUtils.join(", ", names);
}

I'm wondering if there's a more concise way to collect all the names into a String[] object. If this were Ruby, for example, it'd be easy to pull off a short one-liner to do exactly what I need:

ingredients.map(&:name).join(', ')
Matt Huggins
  • 81,398
  • 36
  • 149
  • 218
  • @323go probably Ingredients will have more than a field – Blackbelt May 13 '13 at 13:30
  • duplicate http://stackoverflow.com/questions/205555/the-most-sophisticated-way-for-creating-comma-separated-strings-from-a-collectio – MrSimpleMind May 13 '13 at 13:30
  • This would be a tricky and not a very good way but you can implement toString of `Ingredient` which will return only value of name. And then you can simply use `TextUtils.join(", ",ingredients.toArray())` – Pankaj Kumar May 13 '13 at 13:36
  • 1
    Java 8 will finally allow a ruby-esque way of solving this (either via a simple Lambda or with a method handle directly). – Joachim Sauer May 16 '13 at 15:13
  • a simple `ingredients.stream().map(Ingredient::getName).collect(joining(", " );` would do now. – njzk2 Sep 01 '19 at 23:23

3 Answers3

3

Using Eclipse Collections you can write the following using JDK 5 - 7:

MutableList<Ingredient> ingredients =
        Lists.mutable.with(
                new Ingredient("Flour"),
                new Ingredient("Sugar"),
                new Ingredient("Eggs"),
                new Ingredient("Milk"));
MutableList<String> ingredientNames = ingredients.collect(new Function<Ingredient, String>()
{
    public String valueOf(Ingredient ingredient)
    {
        return ingredient.getName();
    }
});
String delimitedNames = ingredientNames.makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);

Using Java 8 with support for lambdas and method references you can compress it down to the following:

MutableList<Ingredient> ingredients =
        Lists.mutable.with(
                new Ingredient("Flour"),
                new Ingredient("Sugar"),
                new Ingredient("Eggs"),
                new Ingredient("Milk"));
String delimitedNames =
        ingredients.collect(Ingredient::getName).makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);

In this example, using the overloaded form of makeString() without parameters will result in the same string, as makeString() calls makeString(“, “).

String delimitedNames =
        ingredients.collect(Ingredient::getName).makeString();
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);

Note: I am a committer for Eclipse Collections.

Donald Raab
  • 6,458
  • 2
  • 36
  • 44
0

Why don't you use a StringBuilder in the first place? The relevant part of the code:

StringBuilder b = new StringBuilder();
for(Ingredient ingredient: ingredients) {
    b.append(ingredient.getName() + ", ");
}
return b.toString();

Of course you have to remove the last ", " appended which can be done with using the substring method or not appending the last one.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
0
StringBuilder result = new StringBuilder();
for(String string : collectionOfStrings) {
    result.append(string);
    result.append(",");
}
return result.length() > 0 ? result.substring(0, result.length() - 1): "";

see the duplicate post: The most sophisticated way for creating comma-separated Strings from a Collection/Array/List?

Community
  • 1
  • 1
MrSimpleMind
  • 7,890
  • 3
  • 40
  • 45