Hi

I was wonder if there had been any considerations adding an overloaded 
String.join method, that take an Iterable<T> as argument, and a Function<T, 
CharSequence) as a mappingFunction?
This would allow you easily join an Iterable of items that are not Strings, but 
you could easily map to a String by calling toString or another method.

Example usage: String.join(";", List.of(1.234, 2.345, 3.456), 
NumberFormat.getInstance()::format);

I know the same thing is doable using a Stream, for instance the above like: 
Stream.of(1.234, 2.345, 
3.456).map(NumberFormat.getInstance()::format).collect(Collectors.joining(";"));
The String.join version just seems more convenient and easier to read. Also, 
for non-collection Iterable object (i.e. that doesn't have a .stream() method), 
such as java.nio.file.Path, the Stream version becomes rather cumbersome.
for instance joining path elements with a different delimiter would be as easy 
as String.join(";", path, Object::toString);

Implementation wise, the existing implementation only requires slight 
modification to apply the mapping function, and the existing method then just 
becomes a wrapper:

public static <T> String join(CharSequence delimiter,
                              Iterable<T> elements,
                              Function<T, ? extends CharSequence> 
mappingFunction) {
  Objects.requireNonNull(delimiter);
  Objects.requireNonNull(elements);
  Objects.requireNonNull(mappingFunction);
  StringJoiner joiner = new StringJoiner(delimiter);
  for (T elem : elements) {
    joiner.add(mappingFunction.apply(elem));
  }
  return joiner.toString();
}

public static String join(CharSequence delimiter,
                          Iterable<? extends CharSequence> elements) {
  return join(delimiter, elements, Function.identity());
}

Kind regards
Michael Rasmussen

Reply via email to