public static <T> String join(List<T> list, String separator, Function<T, String> function) {
        return list.stream().map(function).map(String::trim).collect(Collectors.joining(separator));
    }
@Test
    public void testJoinWithFunction() {
        final List<FakeSpec> specs1 =
                Arrays.asList(new FakeSpec("a"), new FakeSpec("b"), new FakeSpec("c"));
        assertEquals(join(specs1, ",", FakeSpec::getName), ("a,b,c"));

        final List<FakeSpec> specs2 =
                Arrays.asList(new FakeSpec("a"), new FakeSpec("b"), new FakeSpec("c"));
        assertEquals(join(specs2, ", ", FakeSpec::getName), ("a, b, c"));

        final List<FakeSpec> specs3 =
                Arrays.asList(new FakeSpec(" a"), new FakeSpec("b  "), new FakeSpec(" c "));
        assertEquals(join(specs3, ",", FakeSpec::getName), ("a,b,c"));

        final List<FakeSpec> specs4 =
                Arrays.asList(new FakeSpec(" a"), new FakeSpec("b  "), new FakeSpec(" c "));
        assertEquals(join(specs4, ", ", FakeSpec::getName), ("a, b, c"));
    }