### Question:
StringTuple implements Iterable<String> { public static <S> String joinList(String separator, List<S> list){ StringBuilder sb = new StringBuilder(); for(int i = 0; i < list.size(); i++) { if(i > 0) sb.append(separator); sb.append(list.get(i).toString()); } return sb.toString(); } StringTuple(String s); private  StringTuple(String s, List<String> items); static StringTuple fromParts(String ...parts); static StringTuple fromList(List<String> list); int size(); String get(int index); int find(ConditionFn fn); StringTuple modify(int index, ModifierFn fn); StringTuple remove(int index); StringTuple insert(int index, String value); @Override Iterator<String> iterator(); @Override int hashCode(); @Override boolean equals(Object other); @Override String toString(); static String joinList(String separator, List<S> list);  }### Answer:
@Test void joinList(){ List<String> items = Arrays.asList("a", "bb", "ccc", "12"); assertEquals("a bb ccc 12", StringTuple.joinList(" ", items)); }